I know that the compiler sometimes provides a default copy constructor if you don't implement yourself. I am confused about what exactly this constructor does. If I have a class that contains other objects, none of which have a declared copy constructor, what will the behavior be? For example, a class like this:
class Foo {
Bar bar;
};
class Bar {
int i;
Baz baz;
};
class Baz {
int j;
};
Now if I do this:
Foo f1;
Foo f2(f1);
What will the default copy constructor do? Will the compiler-generated copy constructor in Foo
call the compiler-generated constructor in Bar
to copy over bar
, which will then call the compiler-generated copy constructor in Baz
?
Yes this will do what you expect it to:
The f2 copy constructor Foo::Foo(Foo const&) is called.
This copy constructs its base class and then each member (recursively)
If you define a class like this:
The following methods will be defined by your compiler.
Constructor: Default:
There are actually two default constructors.
One is used for
zero-initialization
while the other is used forvalue-initialization
. The used depends on whether you use()
during initialization or not.Notes: If the base class or any members do not have a valid visible default constructor then the default constructor can not be generated. This is not an error unless your code tries to use the default constructor (then only a compile time error).
Constructor (Copy)
Notes: If the base class or any members do not have a valid visible copy constructor then the copy constructor can not be generated. This is not an error unless your code tries to use the copy constructor (then only a compile time error).
Assignment Operator
Notes: If the base class or any members do not have a valid viable assignment operator then the assignment operator can not be generated. This is not an error unless your code tries to use the assignment operator (then only a compile time error).
Destructor
Looking at your code the following copy constructors are generated:
The compiler provides a copy constructor unless you declare (note: not define) one yourself. The compiler-generated copy constructor simply calls the copy constructor of each member of the class (and of each base class).
The very same is true for the assignment operator and the destructor, BTW. It is different for the default constructor, though: That is provided by the compiler only if you do not declare any other constructor yourself.
The C++ default copy constructor creates a shallow copy. A shallow copy will not create new copies of objects that your original object may reference; the old and new objects will simply contain distinct pointers to the same memory location.
The compiler will generate the needed constructors for you.
However, as soon as you define a copy-constructor yourself, the compiler gives up generating anything for that class and will give and error if you don't have the appropriate constructors defined.
Using your example:
Trying to default instantiate or copy-construct Foo will throw an error since Baz is not copy-constructable and the compiler can't generate the default and copy constroctor for Foo.
Yes, the compiler-generated copy constructor performs a member-wise copy, in the order in which the members are declared in the containing class. If any of the member types do not themselves offer a copy constructor, the would-be copy constructor of the containing class cannot be generated. It may still be possible to write one manually, if you can decide on some appropriate means to initialize the value of the member that can't be copy-constructed -- perhaps by using one of its other constructors.