56920


const修飾子をメンバ関数につけた際のコンパイラの挙動について質問させてください。

[code]

    class Test{
      public:
          int* i;
          Test(){
                i = new int[3];
          }   
          ~Test(){
                delete[] i;
          }   
          void change() const {
                i[0] += 1;
          }   
    };
    
    int main(){
          Test test;
          test.change();
          return 0;
    }
    
[/code]

上記のソースコードで、`change()`の中でメンバ変数`i`の変更を行っているため、コンパイルが通らないことを期待したのですが、問題なくコンパイルされてしまいました。  
配列として`int
i[3];`と宣言するように変更すれば、const修飾子のせいでコンパイルが通らないことは分かったのですが、上記のコードでconst修飾子があるにも関わらずコンパイルが通ってしまう理由を教えていただけると有り難いです。


CC BY-SA 4.0
2019-07-26T12:19:09.963
56919
2019-07-26T13:50:37.303
35270
question
c++
const修飾子をメンバ関数につけた際のコンパイラの挙動について

[code]

    class Test{
      public:
          int* i;
    
[/code]

では、ポインタの`i`は`Test`のメンバーですが、`i`が指している先のメモリは`Test`のメンバーではありません。したがって`const`の範囲外です。`i`が指しているメモリ自体を入れ替えようとすると、コンパイルエラーになります。

[code]

      // コンパイルエラー
      void change() const {
            delete [] i;
            i = new int[3];
      } 
    
[/code]

一方

[code]

    class Test{
      public:
          int i[3];
    
[/code]

とすると、`i`の配列の領域は`Test`の一部として配置されるので、配列全体が`Test`のメンバーです。なので当然`const`で保護されます。


CC BY-SA 4.0
2019-07-26T13:45:12.137
56920
2019-07-26T13:50:37.303
2019-07-26T13:50:37.303
3605
3605
56919
answer