【初心者 C++er Advent Calendar 2015 ではない】C++ における const をつける位置の違い

この記事は初心者 C++er Advent Calendar 2015の6日目の記事になります。
今日はクリスマス・イブ!!ってことで、せっかくなので穴が空いていた6日目の記事を書きました。

と、書いたんですが、すでにいなむさんがに先をこされていました・・・。
まぁでもせっかくなので公開することに。
それはそれとしてカップルとか永遠と爆発してほしい

const とは

constC++ を学び始めると最初の方に出てくるキーワードだと思います。
const 自体はそんなに難しくなく、const をつけることで、定義した変数を不変(後から別の値を代入することができない)にするだけです。

int value = 0;          // const を付けないで定義した変数は
value = 42;             // 後から変数の値を変更できる

const int value2;      // const を付けて定義した変数は
value2 = 42;           // Error: 後から変数の値を変更することができない

主に『定数』など、後から値を変更しない(されない)ような変数を定義したいときに使用します。
また、const をつける位置は『型の前』でも『型の後』でも動作は変わりません。

const int value;   // int const value でも動作は同じ

参照型やポインタ型を絡めて const を定義する場合

const 自体の意味はそこまで難しくないのですが、参照型やポインタ型を含めて定義したい場合には const をつける位置に注意する必要があります。
これは、ポインタと constを組み合わせる場合に

  • * の前に const を付けた場合はポインタを指してる先が不変になる
  • * の後に const を付けた場合はポインタ変数そのものが不変になる

と、いう違いがあるためです。

int value = 42;

// ポインタが指してる実体を変更することができない
const int* p = &value;
p = &value;                   // OK
*p = 10;                      // NG


// ポインタ変数そのものを変更することができない
int* const p2 = &value;
p2 = &value;                  // NG
*p2 = 10;                     // OK

簡単にまとめると

  • const int* → ポインタが指してる実体を書き換えることができない
  • int cosnt → cosnt int と同じ
  • int* const → 定義したポインタ変数を書き換える事ができない

というような違いになります。
ちなみに cosnt int* const という風に両方に const を付けた場合は『変数』も『実体』も不変になります。

int value = 42;

// ポインタが指してる実体もポインタ変数自体もを変更することができない
const int* const p = &value;
p = &value;                      // NG
*p = 10;                         // NG

これは参照型でも同じになります。
このようにポインタ型や参照型で const をつける場合には『何を不変にしたいのか』を意識して const をつける必要があります。