3

私は C++ を再学習しようとしていますが、すべてがどのように機能するかを複雑に理解したいと思う傾向があります (「これを行う方法」だけではありません)。だから、なぜこれがエラーを生成するのか疑問に思っています。はい、オーバーロードされた代入演算子が参照を使用することになっていることは知っています (そして、私がそうしても問題なく動作します) が、この質問への回答が言語規則についてさらに学ぶのに役立つことを願っています.

class some_class {
public:
    int n1;
    some_class(int z) : n1(z) { }
    some_class(some_class &x) : n1(x.n1) { }
    some_class operator= (some_class x) { n1 = x.n1; return *this; }
//  some_class & operator= (some_class & x) { n1 = x.n1; return *this; } works fine
};

main () {
    some_class a(10);
    some_class b(20);
    some_class c(30);
    c = b = a;          // error here
}

コンパイラ (C++03) は、次のc = b = a行でこれを提供します。

In function 'int main()':
   error: no matching function for call to 'some_class::some_class(some_class)'
   note: candidates are: some_class::some_class(some_class&)
   note:                 some_class::some_class(int)
   error:   initializing argument 1 of 'some_class some_class::operator=(some_class)'

b = a正常に動作し、合法的に宣言することを許可されていないコンストラクターを探しているため、混乱します。c = b = aでは、b = aパーツが (参照ではなく) 値を返すため、結果が一時的にコピーされる可能性があることに気付きました。しかし、そうではないのに、なぜc = <temporary>コンパイルエラーになるのb = aでしょうか? 何が起こっているのか分かりますか?

4

5 に答える 5

0

声明では:

c = b = a;

代入演算子は右から左への結合性を持つため、b = a が最初に実行されます。代入演算子は値を返すため、コピー コンストラクターが呼び出されます。一時オブジェクトは非 const 参照によって参照できないため (前述の Stuart Golodetz のように)、コンパイラは some_class::some_class(some_class x) 種類のコンストラクターを探します。見つからないと文句を言っています。

コピー コンストラクターのシグネチャを次のように変更した場合にのみ、コンパイルが成功します。

some_class(const some_class& x);

代入演算子は、他の人が述べたように、伝統的に参照を返します。これは、それらのいくつかを連鎖させることができるためです。ただし、そのように設計することは必須ではありません。

于 2013-09-05T18:10:42.133 に答える