4

私が持っているとします:

class A
{
    A(A& foo){ ..... }
    A& operator=(const A& p) {  }
}

...
A lol;
...

A wow(...)
{

    return lol;
}

...
...
A stick;
stick = wow(...);

次に、最後の行でコンパイル エラーが発生します。しかし、'A&' の前に 'const' を追加すれば問題ありません。

理由を知りたいです。それは正確にどこに問題がありますか?なぜconstでなければならないのかわかりません。

言語: C++

編集しました...その変更は関連があると思います。それはエラーを出します。

4

5 に答える 5

1

を呼び出すとwow、一時オブジェクトであるr値が生成されます。R値を非定数参照に割り当てることはできません。コピーコンストラクターは非定数参照を受け入れるため、呼び出しの結果をwow直接コンストラクターに渡すことはできません。これが、修正を追加constすると問題が修正される理由です。これで、コピーコンストラクターはconst参照を受け入れます。これは、r値が適切にバインドされます。

コピーコンストラクターはコピーするオブジェクトを変更しない可能性があるため、パラメーターはconst-referenceによって渡される必要があります。これは、特定の文書化された状況を除いて、コピーコンストラクターが機能することが期待される方法です。

しかし、sbiが彼の答えで指摘しているように、このコピーコンストラクターはまったく呼び出されるべきではありません。したがって、これはすべて真実ですが、問題とは関係がない可能性があります。コンパイラのバグがない限り。おそらく、コンパイラは2段階の構造を見て、に変換することで仲介者を排除することを決定しました。A stick; stick = wow();しかしA stick = wow(); 、これはバグであり、完全に合法的なコードからコンパイルエラーが発生するという事実からも明らかです。しかし、実際のコードがなければ、実際に何が起こっているのかを言うことは不可能です。コピーコンストラクターに問題が発生する前に、他にもいくつかのエラーが発生するはずです。

于 2010-04-25T08:14:25.700 に答える
1

あなたが言及している問題は次のようなものだと思います。

c ++、匿名(名前のない)変数のオブジェクトの存続期間

ここで重要なのは、C ++ではanonymous-temporariesを参照で渡すことはできず、const参照でのみ渡すことができるということです。

于 2010-04-25T08:14:49.933 に答える
1

次のコードは、Comeauと VC9の両方で完全に正常にコンパイルされます。

class A
{
public:
    A() {}
    A(A&){}
};

A lol;

A wow()
{
    return lol;
}

int main()
{
    A stick;
    stick = wow();
    return 0;
}

これがコンパイラでコンパイルされない場合、コンパイラが壊れていると思われます。もしそうなら、それはあなたが見ている問題に似ていないスニペットを提供するのではなく、実際のコードを貼り付けるべきだったことを意味します.

于 2010-04-25T07:54:56.030 に答える
0

この機能:

A wow(...) 
{  ... }

値渡しのオブジェクトを返します。
これは、関数が呼び出されたポイントにコピーされることを意味します。

この行:

stick = wow(...);  

スティック上でコピー構築を行います。
stick にコピーされた値は、関数 wow() からコピーされた値です。
ただし、wow() の呼び出しの結果は一時オブジェクトであることに注意してください (wow() からコピーされたものですが、まだ変数には含まれていません)。

それでは、A のコピー コンストラクターを見てみましょう。

A(A& foo){ ..... }

一時オブジェクトを参照パラメーターに渡そうとしています。これは許可されていません。一時オブジェクトは const 参照にのみバインドできます。この問題には 2 つの解決策があります。

1) const 参照を使用します。
2) コピー コンストラクターに値渡しします。

残念ながら、ソリューション (2) を使用すると、循環依存になるため、少し行き詰まります。値渡しにはコピー コンストラクターの使用が含まれるため、無限ループに入ります。したがって、解決策は const 参照渡しを使用することです。

于 2010-04-25T08:19:10.523 に答える
0

再現できません。デフォルトのコンストラクターがありませんか、それともコンストラクターを作成するのを忘れていpublicませんか?

http://www.ideone.com/nPsHjを参照してください。

(コピー コンストラクターは、任意の const と volatile の組み合わせといくつかの既定の引数を含む引数を取ることができることcv A&に注意してください。C++ 標準の §[class.copy]/2 を参照してください。)


編集: 興味深いことに、g++-4.3 (ideone) と 4.5 (-pedanticフラグ付き) にはコンパイル エラーはありませんが、g++-4.2 には問題があります:

x.cpp: In function ‘int main()’:
x.cpp:19: error: no matching function for call to ‘A::A(A)’
x.cpp:7: note: candidates are: A::A(A&)
于 2010-04-25T07:50:43.620 に答える