Synthesized Constructors
Because they are so important, sometimes the compiler will automatically write (synthesize) a default and/or copy constructor for us. For many simple classes, the synthesized constructors are exactly what we want!
- The synthesized default constructor is a constructor with an empty member-initialization list and an empty function body. As such, it initializes the member variables exactly as they are written in the class definition. If no initialization is specified in the class definition, the variables will be default initialized (which, for primitive types, means they will have indeterminate values).
- The synthesized copy constructor copy initializes all member variables using the members of the object to be copied.
There are complicated rules that determine when the compiler will decide to synthesize one or more of these constructors (as well as some other functions that we'll discuss later on).
Complicated rules? Oh, no. Are we about to learn a bunch of complicated compiler rules??
Don't worry! In CS 70, we don't expect you to know the rules for when a particular constructor will be synthesized.
Instead, we ask that you explicitly state in your class definitions (i.e., in the header files) whether a particular constructor is being written by you, should be synthesized by the compiler, or shouldn't be allowed.
We tell the compiler what to do with these constructors in the class's header file!
Let's look our options for specifying these constructors for the concrete example of a Cow
class…
Default Constructor Specification
Code | Default Constructor? | Who Writes It? |
---|---|---|
Cow(); |
Yes | You |
Cow() = default; |
Yes | The compiler |
Cow() = delete; |
No | No one |
Notes
- The second form (with
default
) gives us the synthesized default constructor we discussed above. Note thatdefault
here means the compiler should “do the usual thing”, not “make default constructor”. - The third form (with
delete
) results in no default constructor for the class, so trying to create an instance of the class with code likeCow bessie;
will result in a compiler error.
Hay! Why does it say
= default;
? Is that to say it's the default constructor?No. It's to say “please write it”.
What?? Why isn't it
= synthesized;
then?Because
default
was already a keyword used for other things, and I didn't want to add an extra keyword to the language.Meh. I'm all for avoiding work, but even I think that's pretty weak!
So we do the copy constructor the same way (and with the same keywords)?
Yup!
Copy Constructor Specification
Code | Copy Constructor? | Who Writes It? |
---|---|---|
Cow(const Cow& other); |
Yes | You |
Cow(const Cow& other) = default; |
Yes | The compiler |
Cow(const Cow& other) = delete; |
No | No one |
Notes
- The second form's copy constructor will copy all of the data members in the
Cow
class from the already existingCow other
to the newCow
being created.- Each data member will follow the rules we've seen so far: primitives will be copy initialized with the value from the other class, and instances of classes will have their own copy constructors called.
- The third form means there is no copy constructor, so code like
Cow bessie{mabel};
orCow bessie = mabel;
will cause compiler errors.
This is awesome! Can I get the compiler to write my parameterized constructors, too?!?
Nope. How is it supposed to know what parameters to use or what to do with the values that are passed in?
Aw, shucks.
Exercise
We want to create a Chicken
class, with
- A default constructor that sets the member variables to values we choose
- A copy constructor that just copy initializes all of the member variables
We should declare them as
Chicken(); // we will define our own constructor
Chicken(const Chicken& other) = default; // we want a synthesized constructor
Why do we need to write
= default;
? Why can't we just leave it out?Remember that saying
= default
means that you want the compiler to synthesize the constructor. If you leave it out, you're saying that you're going to write that constructor yourself.
Okay, we've seen a bunch of things. Let's head up to the parent page to check our progress so far and maybe take a break.
(When logged in, completion status appears here.)