I have some confusion on initializing objects through direct initialization passing temporary objects..
Here is the code I want to understand:
class Foo {
public:
Foo() { cout << "ctor()\n"; }
Foo(int) { cout << "ctor(int)\n"; }
Foo(const Foo&) { cout << "cpy-ctor\n"; }
Foo& operator=(const Foo&) { cout << "copy-assignment\n"; return *this; }
};
int main() {
Foo();// ctor (temporary object). it is not a function prototype because it requires a return type.
cout << endl;
Foo f; // ctor()
cout << endl;
Foo f2(Foo(7)); // ctor only once
cout << endl;
Foo f3(Foo(Foo(7))); // ctor(int), cpy-ctor() only once
cout << endl;
Foo f4(Foo(Foo(Foo(7)))); // ctor(int), cpy-ctor() only once
cout << endl;
Foo f5(Foo(Foo(Foo(Foo(7))))); // ctor(int), cpy-ctor(), cpy-ctor
cout << endl;
}
- As you can see above, in the first call it is OK. It creates an rvalue object calling the default constructor. Because it doesn't provide a return type the compiler easily treats it as an object declaration.
Foo();
.
Nothing new in the second call Foo f;
which is invoking the default ctor.
- I'm confused by the third call:
Foo(Foo(7))
I thought the compiler would create a temporary object then pass it to the copy constructor to construct objectf2
but it only calls the one-argument constructorFoo(int)
.
Does this mean that the compiler applies some optimization to remove the unnecessary copies?
Now in
Foo f3(Foo(Foo(7)));
it calls ctor and cpy-ctor but why? The same forf4
, though it is different?Finally
Foo f5(Foo(Foo(Foo(Foo(7)))));
invokes the ctor once and the cpy-ctor twice only?
I want to know what is happening exactly, also I tried the same code with no optimization and different levels of it but the result is the same. Thank you.