私は答えに完全に満足していなかったので、私は見てみました:
「より効果的なC++」、スコットマイヤーズ。項目19:「一時的なオブジェクトの起源を理解する」
。ブルース・エッケルの「Temporaries」の報道に関しては、私が思うに、そしてクリスチャン・ラウが直接指摘しているように、それは明らかに間違っています!Grrr!彼は(エッケルの)私たちをモルモットとして使っています!! (彼がすべての間違いを訂正したら、それは私のような初心者にとって良い本になるでしょう)
Meyer:「C ++の真の一時オブジェクトは表示されません。ソースコードには表示されません。ヒープ以外のオブジェクトが作成されても名前が付けられていない場合に発生します。このような名前のないオブジェクトは通常、次の2つの状況のいずれかで発生します。暗黙的な型変換の場合。関数呼び出しを成功させるため、および関数がオブジェクトを返すときに適用されます。」
「最初に、関数呼び出しを成功させるために一時オブジェクトが作成される場合を考えてみてください。これは、関数に渡されるオブジェクトのタイプが、バインドされているパラメーターのタイプと同じでない場合に発生します。」
「これらの変換は、オブジェクトを値で渡す場合、またはreference-to-constパラメーターに渡す場合にのみ発生します。オブジェクトをreference-to-non-constパラメーターに渡す場合には発生しません。」
「一時オブジェクトが作成される2番目の状況は、関数がオブジェクトを返すときです。」
「constへの参照パラメーターが表示されると、そのパラメーターにバインドするための一時オブジェクトが作成される可能性があります。オブジェクトを返す関数が表示されると、一時オブジェクトが作成されます(後で破棄されます)。」
答えの他の部分は、「はじめに」の「マイヤー:効果的なC++」にあります。
「コピーコンストラクタは、同じタイプの別のオブジェクトでオブジェクトを初期化するために使用されます。」
String s1; // call default constructor
String s2(s1); // call copy constructor
String s3 = s2; // call copy constructor
「おそらく、コピーコンストラクターの最も重要な使用法は、オブジェクトを値で渡したり返したりすることの意味を定義することです。」
私の質問について:
f5() = X(1) //what is happening?
ここでは、新しいオブジェクトは初期化されていません。これは初期化ではありません(コピーコンストラクター)。これは割り当てです(Matthieu Mが指摘したように)。
Meyer(上の段落)に従って、両方の関数が値を返すため、一時オブジェクトが作成され、一時オブジェクトが作成されます。Matthieuが擬似コードを使用して指摘したように、次のようになります。
__0.operator=(__1)
ビット単位のコピーが実行されます(コンパイラによって実行されます)。
それにかんする:
void f7(X& x);
f7(f5);
エルゴ、一時的なものは作成できません(マイヤー:上の段落)。宣言されていた場合:void f7(const X& x);
一時的なものが作成されます。
一時オブジェクトが定数であることについて:
Meyerはそれ(およびMatthieu)を次のように述べています。「そのパラメーターにバインドするための一時的なものが作成されます。」
したがって、一時オブジェクトは定数参照にのみバインドされ、それ自体は「const」オブジェクトではありません。
に関して:何X(1)
ですか?
Meyer、Item27、Effective C ++-3e、彼は次のように述べています。
"Cスタイルのキャストは次のようになります:(T)expression//式をT型にキャストします
関数スタイルのキャストは、次の構文を使用します。T(expression)//式をT型にキャストします。 "
X(1)
関数スタイルのキャストもそうです。1
式はタイプにキャストされていX
ます。
そしてマイヤーは再びそれを言います:
「古いスタイルのキャストを使用するのは、明示的なコンストラクターを呼び出してオブジェクトを関数に渡す場合だけです。例:
class Widget {
public:
explicit Widget(int size);
...
};
void doSomeWork(const Widget& w);
doSomeWork(Widget(15)); //create Widget from int
//with function-style cast
doSomeWork(static_cast<Widget>(15));
どういうわけか、意図的なオブジェクトの作成はキャストのように「感じ」ないので、この場合はstatic_castの代わりに関数スタイルのキャストを使用するでしょう。」