Given the following code
#include <iostream>
class Foo {
public:
~Foo();
Foo(const Foo& that);
static Foo create();
private:
Foo();
};
Foo::Foo() {
std::cout << "ctor\n";
}
Foo::~Foo() {
std::cout << "dstor\n";
}
Foo::Foo(const Foo& /* that */) {
std::cout << "copy\n";
}
Foo Foo::create() {
Foo temp;
return temp;
}
int main() {
Foo f = Foo::create();
return 0;
}
In particular the line Foo f = Foo::create(), was there ever a time in C++ history where multiple objects would be created/destroyed? As it is, if I run it I just get
ctor
dstor
So only one object.
In my mind temp and f are different objects, temp is created in the scope of Foo::create which means it has to be destructed inside Foo::create(). A separate object f is created in main.
I get that C++ 11 added move semantics. Before C++ 11 what used to happen?
As another example
#include <iostream>
class Foo {
public:
~Foo();
Foo(const Foo& that);
static Foo create(int v);
void show() const;
private:
Foo(int v);
int v;
int* p;
};
Foo::Foo(int _v) : v(_v) {
p = &v; // <-----------------
std::cout << "ctor\n";
}
Foo::~Foo() {
std::cout << "dstor\n";
}
Foo::Foo(const Foo& /*that*/) {
std::cout << "copy\n";
}
void Foo::show() const {
std::cout << *p << "\n";
}
Foo Foo::create(int v) {
Foo temp(v);
return temp;
}
int main() {
Foo f = Foo::create(123);
f.show();
return 0;
}
Note the line above. p is a pointer to v. So, now, if temp exists on the stack only in the scope of create then if it's copied or moved p will be wrong. The copy constructor is never called, at least in my tests. If I add a move constructor, it's never called either.
I can nest the call to create in other function calls
Foo f2(int v) {
int a = v * 2;
Foo t = Foo::create(a);
return t;
}
Foo f1(int v) {
int a = v * 2;
Foo t = f2(a);
return t;
}
int main() {
Foo f = f1(123);
f.show();
}
I'm missing how t in f2, created in f2s scope is making it back down to main neither being copied nor moved.