I would like to understand when a copy constructor or assignment is called. Assume the following:
class Foo {
public:
   Foo()
   {
      cout << "foo constructor " << this << endl;
      test_ = 44;
   }
   Foo(const Foo& f)
   {
      cout << "foo copy constructor " << this << endl;
      test_ = 55;
   }
   Foo& operator=(const Foo& other)
   {
      cout << "foo copy assignment " << this << endl;
      return *this;
   }
   Foo& operator=(Foo& other)
   {
      cout << "foo copy non-const assignment " << this << endl;
      return *this;
   }
   ~Foo() { cout << "foo destructor  " << this << endl; };
   int bar() const {
      cout << "bar call  " << this << endl;
      return 6;
   }
   int test_;
};
class Model {
public:
   Model()
   {
      foo_ = std::make_unique<Foo>();
   }
   Foo get_foo()
   {
      return *foo_;
   }
   std::unique_ptr<Foo> foo_;
};
int main() {
   cout << "start test 1" << endl;
   {
      Model model;
      Foo foo1 = model.get_foo();
      foo1.bar();
   }
   cout << "end test 1" << endl << endl;
   cout << "start test 2" << endl;
   {
      Model model;
      const Foo& foo2 = model.get_foo();
      foo2.bar();
   }
   cout << "end test 2" << endl;
   cout << "start test 3" << endl;
   {
      Model model;
      model.get_foo().bar();
   }
   cout << "end test 3" << endl;
   return 0;
}
The output is provided at the end.
- Why no copy assignment is called in test 1 and a copy constructor is called?
- Why a copy constructor is called in test 2 and 3?
- what are the exact steps hapenning in test 3 regarding get_foo().bar()?
I would appreciate any type of information/problem you might have noticed in the code (e.g. the fact that get_foo() dereferences a unique pointer).
start test 1
foo constructor 000001D4EF9B6720
foo copy constructor 00000058BED6FA94
bar call  00000058BED6FA94
foo destructor  00000058BED6FA94
foo destructor  000001D4EF9B6720
end test 1
start test 2
foo constructor 000001D4EF9B6F60
foo copy constructor 00000058BED6FAF4
bar call  00000058BED6FAF4
foo destructor  00000058BED6FAF4
foo destructor  000001D4EF9B6F60
end test 2
start test 3
foo constructor 000001D4EF9B6F60
foo copy constructor 00000058BED6FBF4
bar call  00000058BED6FBF4
foo destructor  00000058BED6FBF4
foo destructor  000001D4EF9B6F60
end test 3
