C++クラスでのconstの定義方法について


C++ではconstキーワードを利用して以下のように定義することができると思います:

[code]

    class A{
        const void B(const A const & const z) const;
    };
    
[/code]

この定義を分解すると、以下のパターンに分解できると思います。

[code]

        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);
    
[/code]

これらの定義の仕方についての違いがわかりません。もし違いがあるとするならば、その違いについて教えて下さい。



[code]

    class A{
        const void B(const A const & const z) const;
    //  ~~~~         ~~~~~   ~~~~~   ~~~~~    ~~~~~
    //  (1)          (2)     (3)     (4)      (5)
    };
    
[/code]

メンバ関数で`const`キーワードを書いた位置と、それぞれの意味は下記の通りです：

  * (1) 戻り値型に対するconst修飾となります。このメンバ関数の戻り値型は`const void`です。（この例だと実用上の意味はありませんが）
  * (2) メンバ関数宣言において、型`A`に対するconst修飾となります。このメンバ関数の1個目の引数型は`const A &`（`const A`への参照型）です。
  * (3) (2)と完全に同じ意味です。ただし(2)と(3)の2箇所同時に`const`を置くとコンパイルエラーになり、どちらか一方にしか指定できません。
  * (4) メンバ関数定義において、関数パラメータ変数`z`に対するconst修飾となります。この例では "参照型に対するconst修飾" となるため、コンパイルエラーです。例えばポインタ型`const A * const z`であれば、変数`z`の型は "`const A`型へのconstポインタ" のように使えます。
  * (5) `this`オブジェクトに対するconst修飾、いわゆる「constメンバ関数」となります。このメンバ関数内での`this`の型は`const A *`です。



[code]

    class A{
        const void B(const A const & const z) const;
    //  ~~~~         ~~~~~   ~~~~~   ~~~~~    ~~~~~
    //  (1)          (2)     (3)     (4)      (5)
    };
    
[/code]

メンバ関数で`const`キーワードを書いた位置と、それぞれの意味は下記の通りです：

  * (1) 戻り値型に対するconst修飾となります。このメンバ関数の戻り値型は`const void`です。（この例だと実用上の意味はありませんが）
  * (2) メンバ関数宣言において、型`A`に対するconst修飾となります。このメンバ関数の1個目の引数型は`const A &`（`const A`への参照型）です。
  * (3) (2)と完全に同じ意味です。ただし(2)と(3)の2箇所同時に`const`を置くとコンパイルエラーになり、どちらか一方にしか指定できません。
  * (4) メンバ関数定義において、関数パラメータ変数`z`に対するconst修飾となります。この例では "参照型に対するconst修飾" となるため、コンパイルエラーです。例えばポインタ型`const A * const z`であれば、変数`z`の型は "`const A`型へのconstポインタ" のように使えます。
  * (5) `this`オブジェクトに対するconst修飾、いわゆる「constメンバ関数」となります。このメンバ関数内での`this`の型は`const A *`です。

