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 f2
s scope is making it back down to main neither being copied nor moved.