I've been messing with references wrapped in container classes. Why is the following code legal and appear to behave correctly?
#include <iostream>
class Foo
{
public:
Foo( int i ) : i_( i ) {}
int i_;
};
class FooWrapper
{
public:
FooWrapper( Foo& foo ) : foo_( foo ) {}
Foo& foo_;
};
int main( int argc, char* argv[] )
{
Foo foo( 42 );
FooWrapper fw( foo );
FooWrapper fw2 = fw;
std::cout << fw2.foo_.i_ << std::endl;
return 0;
}
In the absence of an explicit operator=
, I believe C++ does a memberwise copy. So when I do FooWrapper fw2 = fw;
, is this not two operations: (1) create FooWrapper fw
with a default ctor followed by (2) assignment from fw
to fw2
? I'm sure this isn't happening, because a reference can't be created uninitialized, so is the creation of fw2
actually treated as a copy construction?
I'm sometimes unclear on the roles of copy construction vs. assignment; they seem to bleed into each other sometimes, as in this example, but there's probably some rule I'm unaware of. I'd be grateful for an explanation.
In the line below, you are constructing fw2
by making it a copy of fw
. That is, you are invoking the copy-constructor.
FooWrapper fw2 = fw;
Example
Here is an (online) example on how default constructor, copy constructor, copy assignment operator, and move assignment operator (from C++11) are invoked.
#include <iostream>
struct foo
{
foo() {std::cout << "Default constructor" << '\n';}
foo(foo const&) {std::cout << "Copy constructor" << '\n';}
foo& operator=(foo const&) {std::cout << "Copy assignment operator" << '\n'; return *this; }
foo& operator=(foo &&) {std::cout << "Move assignment operator" << '\n'; return *this; }
};
int main( int argc, char* argv[] )
{
foo a; // Default constructor
foo b = a; // Copy constructor
foo c; // Default constructor
c = b; // Copy assignment operator
b = std::move(c); // Move assignment operator
}