C++のconstの復習


このエントリーをはてなブックマークに追加

よくわからなくなるのでメモ。

ポインタ変数につけるconst

ポインタ変数に対してconstをつけるときは、場所によって効果が違う。

#include <iostream>

using namespace std;

int main(){
    int a = 100;
    int b = 100;

    // ポインタが指す先を変更できない
    const int* p = &a;
    // *p = 1000; // NG!
    p = &b; // OK!

    // ポインタの差し替えができない
    int* const q = &a;
    *q = 1000; // OK!
    // q = &b; // NG!

    // 両方できない
    const int* const r = &a;
    *r = 1000;
    r = &b;

    return 0;
}

メンバ関数につけるconst

メンバ関数の最後にconstをつけると、「そのメンバ関数は、メンバ変数の値を変更しません」という意味になる。

class CMyClass
{
private:
    int a;

public:
    void func1() const {
        cout << "a = " << a << endl;
        // a = 100; // NG! constがついているメンバ関数内で、メンバ変数の値を変更するのは禁止
    }
};


constがついてるメンバ関数とついてないメンバ関数とは区別される。どちらのメンバ関数が呼ばれるかは、そのクラスのオブジェクトがconstかどうかで決まる。

#include <iostream>

using namespace std;

class CMyClass
{
private:
    int a;

public:
    // コンストラクタ
    CMyClass() : a(0){};

    // この2つの関数は区別される
    void func1() const {
        cout << "func1() const" << endl;
    }
    void func1() {
        cout << "func1() " << endl;
    }
};

int main(){
    const CMyClass c1;
    c1.func1();  // const付きのfunc1()が呼ばれる

    CMyClass c2;
    c2.func1();  // const無しのfunc1()が呼ばれる

    return 0;
}

出力結果は以下の通り。

func1() const
func1()


もしCMyClassにvoid func1() constだけあって、void func1()がない場合は、c2.fucn1()は(仕方なく?)void func1() constの方を呼び出すようだ。

#include <iostream>

using namespace std;

class CMyClass
{
private:
    int a;

public:
    // コンストラクタ
    CMyClass() : a(0){};

    void func1() const {
        cout << "func1() const" << endl;
    }
};

int main(){
    const CMyClass c1;
    c1.func1();

    CMyClass c2;
    c2.func1(); // この場合はconst付きの方が呼ばれる

    return 0;
}

出力例は以下の通り。

func1() const
func1() const

参考

  • Effective C++
  • C++ポケットリファレンス