0

私の投稿の1つへのコメントは私に興味を持った:

私も。また、アクセサー/ミューテーターにも同じ名前を付けます。

setBar(int bar)同じ名前のミューテーターの代わりにいつも使っていたので、これについて疑問に思いました。知りたいのですが、コンパイラはconst識別子に基づいて実行時に何が変化するかを判断できますか、それともパラメータがあるため同じ関数名を使用できますか?

これはうまくコンパイルされますか?

class Foo
{
   int bar_;

   public:
      int bar() { return bar_; }
      void bar(int bar) { bar_ = bar; }
}

または、これを実行する必要がありますか(とにかくこれを実行する必要があることを認識しています。これについては、一緒に実行してください)。

int bar() const { return bar_; }

どっちがどっちかわからない。定数の正確さは重要なので、1つは変更し、もう1つは変更しないので、コンパイラーにオーバーロードに反対してもらいたいと思います。

なぜこのように機能するのですか?

4

3 に答える 3

4

コンパイラーが最初に確認するのは、関数に渡すパラメーターの数とタイプです。これにより、 -nessbarを確認する必要が生じる前に、オーバーロードが解決されます。const

bar()としてマークを付けなかった場合、オブジェクトのインスタンスをconst初めて呼び出そうとしたときに、コンパイラがそのことを通知します。bar()const

于 2009-08-05T00:59:32.590 に答える
2

コンパイラーは、実際にはオブジェクトを変更しない非 const メンバー関数を作成することを妨げません。これは、オブジェクトが const 参照を介して変更されないことを保証するだけの const-correctness の違反ではありません。ここでの原則は、const は関数が変化しない可能性があることを示し、non const は関数が必要に応じて自由に変化できることを意味します。変更を約束する方法はなく、コンパイラにそれを強制させる方法はありません。これは、呼び出し元に使用するにはあまりにも漠然とした保証になると思います。

Greg が言うように、const オブジェクトで非 const メンバ関数を呼び出そうとすると、コンパイラは反対します (繰り返しますが、実際に変化するかどうかは関係ありません。重要なのは、const として宣言されているかどうかだけです)。

于 2009-08-05T01:15:19.713 に答える
0

理解を容易にするために、オブジェクトに対して非 const メソッドが呼び出されると、オブジェクトが変更されるとコンパイラが想定していることを考慮してください。

したがって、const メソッドでは、データ メンバーの 1 つまたはクラスの別の非 const メソッドに対して非 const メソッドを呼び出すと、コンパイラはエラーを通知します。

演算子をメソッドと見なすこともできます (一部の演算子は、メソッドとしてではなく、単純化のためにフレンド関数として定義できます...)。たとえば、代入演算子 (operator=) はデフォルトで非 const です。つまり、次のようなことをすると

void MyClass::MyConstMethod() const
{
   classMember = value;
}

コンパイラは、const メソッド内では const オブジェクトである classMember の代入演算子を呼び出したと見なします。operator= は const ではないため、コンパイラ エラーが報告されます。

于 2009-08-05T08:11:22.107 に答える