C/C++のconst修飾子 (ポインタが関連するケース)
[履歴] (2013/07/09 08:15:26)
最近の投稿
注目の記事

概要

constで修飾された変数はread onlyになり、初期化 (必須) 時に与えられた値は変更されないことを明示的に記述できます。ただし、constは外すことが可能なため保証はされません。

const int num = 123;

上記の例は簡単ですが、ポインタ変数にconstをつける場合はややこしくなります。

いくつかの紛らわしい修飾パターン

パターン1

int num = 123;
const int *ptr1 = #
int const *ptr2 = #

ptr1とptr2は同じ意味で、ptr1の形式がよく使われるように思います。その意味は、「ptr1 (あるいはptr2) は、read onlyなint (すなわちconst int) へのポインタ」となります。そのため、指す先の値を変更しようとして、

*ptr1 = 777;

などとするとエラーになります。ポインタの指す対象はconst (read only) でないため、

int num2 = 777;
ptr1 = &num2;

とすることは可能です。初期化も不要で、

const int *ptr1;
int num = 123;
ptr1 = #

とできます。

パターン2

int num = 123;
int * const ptr3 = #

これは「ptr3が指す対象は変更できず (const)、int型変数numのアドレスを初期値として持つ」という意味になります。そのため、先程とは逆に

*ptr3 = 777;

は可能で、

int num2 = 777;
ptr3 = &num2;

はエラーとなります。

パターン3

パターン1とパターン2を組合せて、

const int * const ptr4 = #

とすると、指す対象も指す先の値も固定され変更できません。

実用的なパターンはひとつ

ポインタが指す対象を固定したいことは稀なため、実際の現場ではパターン2,3はあまり見ないように思います。一方で指す先の値を変更しないことを明示するパターン1は、関数の引数でよく用いられる気がします。

sample.cpp

#include <iostream>
using namespace std;

void sum(const int *a, const int *b, int *res) {
    *res = *a + *b;
}

int main() {
    int a=1, b=2, res;
    sum(&a,&b,&res);
    cout << res << endl;
    return 0;
}

実行例

$ g++ sample.cpp && ./a.out
3
関連ページ
    サンプルコード #include <iostream> #include <vector> using namespace std; // クラス内での使用 class MyClass { public: typedef int MyPublicValueType; // protected, private も可能 MyClass(); public: MyPubli