質問: C++ではconstキーワードを利用して以下のように定義することができると思います: ``` class A{ const void B(const A const & const z) const; }; ``` この定義を分解すると、以下のパターンに分解できると思います。 ``` const void C(A & z); void D(const A & z); void E(A const & z); void F(A & z) const; void G(A & const z); ``` これらの定義の仕方についての違いがわかりません。もし違いがあるとするならば、その違いについて教えて下さい。
回答: 質問が不明確な部分があるので次のように解釈します。 質問 次のようなクラスAを考える。 ``` class A { A() : a(), b() {} const void C( A & z); void D(const A & z); void E(A const & z); void F(A & z) const; //void G(A & const z); int a; const int b; }; ``` クラスAのメンバ関数C,D,E,F(,G)の違いを述べよ。 回答 * const void C(A& z) 返り値の型:const void 呼出し可能:zのC,D,E,FとthisのC,D,E,F 読出し可能:zのa,bとthisのa,b 書込み可能:zのaとthisのa 備考:const voidはconst修飾されていないvoidと区別されます(これはvoidだけでなく他の型でも同様です)。 しかしvoid型変数は存在できないので型演算の時以外でこれが問題になることは無いでしょう。 * void D(const A& z) * void E(A const& z) 返り値の型:void 呼出し可能:zのFとthisのC,D,E,F 読出し可能:zのa,bとthisのa,b 書込み可能:thisのa 備考:const修飾子の位置が違うだけでDとEは(名前を除き)宣言の形は同じです。 * void F(A& z) const 返り値の型:void 呼出し可能:zのC,D,E,FとthisのF 読出し可能:zのa,bとthisのa,b 書込み可能:zのa * void G(A& const z) const修飾子を参照型の後に書くことはできません。 (ただし、ポインタ型では可能で、意味が異なります。"const T* t"もしくは"T const* t"はポインタtの指しているオブジェクトがconst修飾されます。"T* const t"はポインタtがconst修飾されます。) まとめると今回の質問で考慮しなければいけないことは、以下の事柄だと思います。 * クラスAのメンバ関数は引数にとったクラスA型のオブジェクトのメンバにたとえ非公開であってもアクセスできる。(ちなみに今回のクラスAのメンバC,D,E,F,a,bは全て非公開になっている) * ただし、基本的にconst修飾されたオブジェクト(今回はD,Eの仮引数zとb)に変更を加えることはできない。 * また、基本的にconstメンバ関数(今回はF)はメンバ変数(今回はa(,b))に変更を加えることはできない。(constメンバ関数は非constメンバ関数を基本的には呼び出せない) * "const T&"と"T const&"に違いはない。"T& const"はできない。 * "const T MemberFunc()"と"T MemberFunc() const"は根本的に意味が異なる。前者は返り値型がconst修飾され、後者はconstメンバ関数となる。