web-dev-qa-db-ja.com

C ++「const」キーワードの説明

C++で書かれたチュートリアルとコードを読むとき、私はよくconstキーワードにつまずきます。

次のように使用されていることがわかります。

const int x = 5;

これは、xが定数変数であり、おそらく読み取り専用メモリに格納されることを意味することを知っています。

しかし、何ですか

void myfunc( const char x );

そして

int myfunc( ) const;

34
RajX
void myfunc(const char x);

これは、パラメータxが関数内で値を変更できないcharであることを意味します。例えば:

void myfunc(const char x)
{
  char y = x;  // OK
  x = y;       // failure - x is `const`
}

最後の1つ:

int myfunc() const;

これはクラス宣言内にない限り違法です-constメンバー関数はクラスメンバーの変更を禁止します-const非メンバー関数は使用できません。この場合、定義は次のようになります。

int myclass::myfunc() const
{
  // do stuff that leaves members unchanged
}

constメンバー関数で変更可能にする必要がある特定のクラスメンバーがある場合は、mutableとして宣言できます。例はメンバーlock_guardは、クラスのconstおよび非constメンバー関数をスレッドセーフにしますが、must自身の内部操作中に変更します。

54
Steve Townsend

最初の関数の例は多かれ少なかれ無意味です。より興味深いものは次のとおりです。

_void myfunc( const char *x );
_

これは、コンパイラに_*x_のcontentsが変更されないことを伝えます。つまり、myfunc()内では次のようなことはできません。

_strcpy(x, "foo");
_

C++メンバー関数の2番目の例は、呼び出しによってオブジェクトの内容が変更されないことを意味します。

与えられた:

_class {
  int x;
  void myfunc() const;
}
_

someobj.myfunc()は次のような変更を許可されていません。

_x = 3;
_
10
Paul Roub

この:

void myfunc( const char x );

関数内でxを変更できないことを意味します。つまり、これは違法です。

void myfunc( const char x ) {
    x = ...;
}

一方:

int myfunc() const;

myfunc()がクラス内のメソッドである場合にのみ意味があります。基本的に、メソッドはクラスインスタンスを変更できないことを意味します(つまり、instance.myfunc()を呼び出す前後のインスタンスの状態は同じになります)。

3
Lie Ryan

変数識別子の前のconstは、変数を初期化でき、その後は変更できないことを示します。

クラスメソッド名の後、constは、メソッドがクラスの観測可能な状態を変更しないことを示します。 mutableキーワードを使用すると、内部データを変更できます。

ポインターまたは参照変数の前のconstは、参照されたデータを変更するために識別子が使用されないことを示しますが、他の方法で変更される場合があります。

const int *pInt = &x;

Constは、ポインター自体を変更できないことを示すためにも使用できます。

int * const pInt = &x;
2
Andy Thomas

私は非常に良い説明を見つけました: http://duramecho.com/ComputerInformation/WhyHowCppConst.html

基本的にすべての混乱は、キーワードconstのさまざまなユースケースにあります。 constを配置する場所に応じて、何かが不変であるべきか、何かが他の何かを変更できないようにすべきであると言います。 「何か」は、変数、ポインター、または関数/メソッドである可能性がありますが、オブジェクトの関数またはメンバー変数に渡される変数の値を変更できないようにする必要があります。

1
lumbric

const修飾子は、constとして定義された変数/ポインターがプログラムによって変更されず、明示的な初期化またはハードウェア依存の手段から値を受け取ることを意味します。

パラメーター宣言でconstとして定義されているポインターは、関数コードが指すものを変更しません。基本的に、ポインタを使用でき、それはほとんど「読み取り専用」として機能します。

例えば:-

void foo(const char *x)
{
    while(*x)
    {
        if(*x==' ') cout << '-'; //printing - when a space is encountered
        else cout << *x;
        x++;
    }
}

上記の機能は問題なく、エラーは表示されません。ただし、fooに渡された文字列を変更できるものがある場合。スペースを$に置き換える関数を言う。 $を印刷せず、$に変更します。このようなもの:-

void foo(const char *x)
{
    while(*x)
    {
        if(*x==' ') *x = '$'; //printing - when a space is encountered
        else cout << *x;
        x++;
    }
}

コンパイルされません。つまり、読み取り専用メモリの場所への割り当てエラー。

0
Divyang Vashi

2つの違いは、最初の型がvoid(char)型であり、2番目の型がint()const型であることです。

末尾にconstを持つそのような型を持つ関数は、クラスのメンバー関数にしかなれません。これは、メンバー関数がクラス値(thisが参照するもの)を変更しないことを意味します)クラス外から見たとき。コンパイラーはそれをある程度チェックし、constメンバー関数のクラスメンバーに直接書き込むとコンパイル時エラーが発生し、関数はconstメンバー関数のみを直接呼び出すことができます(特別なディレクティブが存在するため、メンバが書き込むコンパイラは、外部から見たクラスの値を変更しません。これは、mutableキーワードによって行われます)。

提示した関数には、char const型のパラメーターがありました。そのようなパラメーターは、その関数内では変更できません。ただし、関数の型には影響せず、関数の呼び出し元には影響しません。

void myfunc(const char x)は、あなたの例の_const int x = 5_と非常に似ています:関数myfunc内でローカルに利用可能な定数を宣言します。定数なので、その値は変更できません。

int myfunc() constは、クラスのメンバー関数です。 constは、関数が実行されるクラスのインスタンスを関数が変更しないことを示します。そのため、関数内では、_this->foo = 7_のようなことをしたり、constではない他の関数を呼び出したりすることはできません。

0
Flinsch