2

私は2つのゲッターメンバーを持っています:

Node* prev() { return prev_; }
int value()  { return value_ }

const 識別子がないことに注意してください (忘れてしまいましたが、これが機能しない理由を知りたいです)。これをコンパイルしようとしています:

Node(Node const& other) : prev_(other.prev()), value_(other.value()) { }

コンパイラはこれを拒否します。C++ では、次のような関数パラメーターで非 const から const への変換が許可されていると思いました。

{
   Foo(int bar);
}

Foo(const int bar)
{
   //lala
}

コピー コンストラクターで同じことができないのはなぜですか? const 識別子は、何も変更しないことを約束することを意味します。

4

5 に答える 5

14

非 const から const への変換を行おうとしているわけではありません。const ではなく、const 参照 (prev と value の呼び出し) ではない 2 つのメソッドを呼び出そうとしています。このタイプの操作は、const セマンティクスによって厳密に禁止されています。

代わりにできることは、フィールド prev_ と value_ を直接使用することです。これは同じ型のメンバーであるため、const オブジェクトで使用できるプライベートにアクセスできます。

于 2009-07-31T16:07:54.997 に答える
3

C++ では、次のような関数パラメーターで非 const から const への変換が許可されていると思いました。

正反対のことをしようとしています: Const から非 const へ。非 const メンバー関数を呼び出すと、コンパイラは式をバインドします (これは、ポインターをバインドするNode constための aです)。したがって、const を削除します。const オブジェクトで非 const 関数を呼び出すため、許可されません。Node&this

/* class Foo */ {
   Foo(int bar);
}

/* Foo:: */ Foo(const int bar)
{
   //lala
}

そのコードはまったく別のものです。関数 (コンストラクター) を 2 回宣言しますが、唯一の違いは、パラメーターが const である場合とそうでない場合です。関数の型はどちらの場合も同じであるため、競合しません (constパラメーターは関数本体内でローカルにのみ影響を与えます。呼び出し元に違いはありません)。さらに、このコードには呼び出しが含まれていません (最初のブロックが何らかの関数内にあると仮定します)。

疑問がある場合: 上記の 2 つのバージョンが同一である場合、なぜ以下のバージョンは同一ではないのでしょうか? 次に、これは、以下に別のレベルの間接性が含まれているためです。以下では、参照自体 (最上位レベルconst) は const ではありません (参照自体を直接配置することはできません) が、参照される型は const です。このとき、関数の型を決定する際に const は無視されません。

/* class Foo */ {
   Foo(int &bar);
}

// different thing, won't work!
/* Foo:: */ Foo(const int &bar)
{
   //lala
}
于 2009-07-31T16:12:12.570 に答える
2

他の人が述べたように、コンパイラが許可しない const オブジェクトで非 const メソッドを呼び出しています。

これを簡単に修正するには、getter 関数を const としてマークするだけです。

Node* prev() const { return prev_; }
int value()  const { return value_; }

オブジェクトを変更しないため。const オブジェクトで呼び出すことができるようになりました。実際、クラスのユーザーが const オブジェクトを使用してこれらの getter を呼び出せるように、これはおそらく何らかの方法で行う必要があります。

ただし、コピー ctor が次のようになっている場合は、別の問題が発生する可能性があります。

Node(Node const& other) : prev_(other.prev()), value_(other.value()) { }

prev_コピーとオリジナルは両方とも、メンバー内の同じ Node オブジェクトを指します。クラスのセマンティクスによっては、これで問題ない場合もありますが、所有権の問題またはその他の論理的な不一致である可能性があります。

于 2009-07-31T16:54:12.923 に答える
2

その通りです。const は、何も変更しないことを約束することを意味します。コンパイラは、何も変更しないことを約束していないオブジェクトのメソッドを呼び出すことを許可しないことで、約束を守らせています。

于 2009-07-31T16:09:27.240 に答える
2

コンストラクターの宣言ではNode(Node const& other)、引数otherが宣言されconstます。これは、メソッドのみを呼び出すことができることを意味しますconst

どちらも非メソッドであるコンストラクターから呼び出しother.prev()ているため、コンパイラーは文句を言います。other.value()const

于 2009-07-31T16:17:30.533 に答える