サーチ…


構文

  • const型myVariable =初期; // const変数を宣言します。変えられない
  • constタイプ&myReference = myVariable; // const変数への参照を宣言します。
  • const型* myPointer =&myVariable; // constへのポインタを宣言します。ポインタは変更できますが、ポインタを介して基礎となるデータメンバを変更することはできません
  • タイプ* const myPointer =&myVariable; // constポインタを宣言します。ポインターを他のものを指すように再割り当てすることはできませんが、基になるデータ・メンバーは変更することができます
  • constタイプ* const myPointer =&myVariable; // constへのポインタをconstに宣言します。

備考

マークされた変数const 1に変更することはできません。 const以外のオペレーションを呼び出そうとすると、コンパイラエラーが発生します。

1:まあ、それはconst_castを通して変更することができますが、あなたはほとんどそれを使うべきではありません

Constローカル変数

宣言と使用法。

// a is const int, so it can't be changed
const int a = 15;  
a = 12;           // Error: can't assign new value to const variable
a += 1;           // Error: can't assign new value to const variable

参照とポインタのバインディング

int &b = a;       // Error: can't bind non-const reference to const variable
const int &c = a; // OK; c is a const reference

int *d = &a;      // Error: can't bind pointer-to-non-const to const variable
const int *e = &a // OK; e is a pointer-to-const

int f = 0;
e = &f;           // OK; e is a non-const pointer-to-const,
                  // which means that it can be rebound to new int* or const int*

*e = 1            // Error: e is a pointer-to-const which means that
                  // the value it points to can't be changed through dereferencing e

int *g = &f;
*g = 1;           // OK; this value still can be changed through dereferencing
                  // a pointer-not-to-const

Constポインタ

int a = 0, b = 2;

const int* pA = &a; // pointer-to-const. `a` can't be changed through this
int* const pB = &a; // const pointer. `a` can be changed, but this pointer can't.
const int* const pC = &a; // const pointer-to-const.

//Error: Cannot assign to a const reference
*pA = b;

pA = &b;

*pB = b;

//Error: Cannot assign to const pointer
pB = &b;

//Error: Cannot assign to a const reference
*pC = b;

//Error: Cannot assign to const pointer
pC = &b;

Constメンバ関数

クラスのメンバ関数はconst宣言することができます。この関数はコンパイラと将来の読者に、この関数がオブジェクトを変更しないことを通知します。

class MyClass
{
private:
    int myInt_;
public:
    int myInt() const { return myInt_; }
    void setMyInt(int myInt) { myInt_ = myInt; }
};

constメンバ関数では、 thisポインタは事実上const MyClass *ではなくconst MyClass * MyClass *です。つまり、関数内のメンバー変数を変更することはできません。コンパイラは警告を発します。したがって、 setMyIntconst宣言できませんでした。

できるだけメンバ関数をconstとしてマークするべきです。 const MyClassでは、 constメンバー関数だけを呼び出すことができます。

staticメソッドはconstとして宣言できません。これは、静的メソッドがクラスに属し、オブジェクトに対して呼び出されないためです。したがって、オブジェクトの内部変数を決して変更することはできません。したがって、 staticメソッドをconstとして宣言することは冗長になります。

constおよび非const getterメソッドでコードの重複を避ける

const修飾子だけが異なるC ++のメソッドでは、オーバーロードすることができます。場合によっては、一部のメンバへの参照を返すゲッタの2つのバージョンが必要な場合があります。

Fooクラスとし、同じ操作を実行する2つのメソッドを持ち、 Bar型のオブジェクトへの参照を返します。

class Foo
{
public:
    Bar& GetBar(/* some arguments */)
    {
        /* some calculations */
        return bar;
    }
    
    const Bar& GetBar(/* some arguments */) const
    {
        /* some calculations */
        return bar;
    }

    // ...
};

それらの唯一の違いは、1つのメソッドが非constであり、非const参照(オブジェクトの変更に使用できる)を返し、2番目のメソッドがconstであり、const参照を返すという点です。

コードの重複を避けるために、あるメソッドを別のメソッドから呼び出すという誘惑があります。しかし、非constメソッドをconstオブジェクトから呼び出すことはできません。しかし、非constのものからconstメソッドを呼び出すことができます。 const修飾子を削除するには 'const_cast'を使用する必要があります。

解決策は次のとおりです。

struct Foo
{
    Bar& GetBar(/*arguments*/)
    {
        return const_cast<Bar&>(const_cast<const Foo*>(this)->GetBar(/*arguments*/));
    }
    
    const Bar& GetBar(/*arguments*/) const
    {
        /* some calculations */
        return foo;
    }
};

上記のコードでは、我々はのconstのバージョンを呼び出すGetBar非constからGetBar const型にこれをキャストすることによって: const_cast<const Foo*>(this) 。非constからconstメソッドを呼び出すので、オブジェクト自体は非constであり、constをキャストすることは許されています。

次のより完全な例を調べてください。

#include <iostream>

class Student
{
public:
    char& GetScore(bool midterm)
    {
        return const_cast<char&>(const_cast<const Student*>(this)->GetScore(midterm));
    }
    
    const char& GetScore(bool midterm) const
    {
        if (midterm)
        {
            return midtermScore;
        }
        else
        {
            return finalScore;
        }
    }
    
private:
    char midtermScore;
    char finalScore;
};

int main()
{
    // non-const object
    Student a; 
    // We can assign to the reference. Non-const version of GetScore is called
    a.GetScore(true) = 'B';
    a.GetScore(false) = 'A';
    
    // const object
    const Student b(a); 
    // We still can call GetScore method of const object,
    // because we have overloaded const version of GetScore
    std::cout << b.GetScore(true) << b.GetScore(false) << '\n'; 
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow