8

私がこれを行う場合:

// In header 
class Foo {
void foo(bar*);
};

// In cpp
void Foo::foo(bar* const pBar) {
//Stuff
}

コンパイラは、Foo::foo の署名が一致しないことを訴えません。ただし、次の場合:

void foo(const bar*); //In header
void Foo::foo(bar*) {} //In cpp

コードはコンパイルに失敗します。

何が起こっている?gcc 4.1.x を使用しています

4

7 に答える 7

15

最初に、変数を編集しないことをコンパイラーに約束しましたが、クラスの他のユーザーには約束しませんでした。

2 番目の例では、変数を編集しないことをクラスの他のユーザーに約束しましたが、その約束を守れませんでした。

また、明確な違いがあることにも注意してください。

bar* const variable

const bar* variable

const bar* const variable

最初の形式では、ポインターは変更されませんが、指しているオブジェクトを編集できます。2 番目の形式では、ポインターを編集 (別のオブジェクトをポイント) できますが、ポインターが指す変数を編集することはできません。最終的なフォームでは、ポインターもポインターが指すオブジェクトも編集しません。参照

述べられた質問にもう少し明確にするために、いつでも少ないよりも多くの const を約束することができます。与えられたクラス:

class Foo {
    void func1 (int x);
    void func2 (int *x);
}

次の実装をコンパイルできます。

Foo::func1(const int x) {}
Foo::func2(const int *x) {}

また:

Foo::func1(const int x) {}
Foo::func2(const int* const x) {}

問題なく。変数を編集できる可能性があることをユーザーに伝えました。あなたの実装では、この特定の実装ではこれらの変数を編集しないことをコンパイラに伝えました。ユーザーへの約束を破っていないので、コードはコンパイルされます。

于 2008-11-06T19:07:02.183 に答える
6

この質問この質問、およびこの質問を参照してください。

基本的に、const は、関数がポインターの値を変更しないことを意味するだけです。ポインターの内容は、ヘッダーの署名と同じように const ではありません。

于 2008-11-06T19:08:55.037 に答える
2

最初の例のconstキーワードは無意味です。ポインターを変更する予定はないと言っています。ただし、ポインターは値で渡されたため、変更するかどうかは問題ではありません。呼び出し元には影響しません。同様に、次のようにすることもできます。

// In header 
class Foo {
void foo( int b );
};

// In cpp
void Foo::foo( const int b ) {
//Stuff
}

これを行うこともできます:

// In header 
class Foo {
void foo( const int b );
};

// In cpp
void Foo::foo( int b ) {
//Stuff
}

intは値渡しなので、constness は関係ありません。

2 番目の例では、関数が 1 つの型へのポインターを受け取ると言っていますが、別の型へのポインターを受け取るように実装しているため、失敗します。

于 2008-11-06T19:22:20.873 に答える
0

前者ではconst、インターフェイスには影響せず、実装のみに影響します。bar*あなたはコンパイラに「この関数内の値を変更するつもりはない」と言っています。ポインタが指し示すものは引き続き変更できます。後者では、 が指すbar構造を変更しないことをコンパイラ (およびすべての呼び出し元) に伝えています。bar*

于 2008-11-06T19:07:16.350 に答える
0

したがって、2番目の const は次のとおりです。

void Foo::foo(const bar* const);

メソッド署名の一部ではありませんか?

于 2008-11-06T19:13:44.200 に答える
0

これは、ポインター以外の変数型を使用すると理解しやすくなります。たとえば、次の関数宣言を使用できます。

void foo( int i );

定義は次のようになります。

void foo( const int i ) { ... }

定義側で変数 i が const かどうかは実装の詳細です。その関数のクライアントには影響しません。

于 2008-11-06T19:33:30.650 に答える
0

void Foo::foo(bar* const pBar)ポインター自体 (const かどうか) をどのように扱うかは、ルーチンの外では少しも問題にならないため、おそらくあまり気にしません。C の規則では、pBar への変更はいずれの方法でも foo の外に移動しないと規定されています。

ただし、そうである場合(const bar* pBar)、違いが生じます。これは、コンパイラが呼び出し元が非 const オブジェクトへのポインターを渡すことを許可しないことを意味するためです。

于 2008-11-06T19:38:44.210 に答える