As you start overloading constructors,
you often notice that the code used to initialize objects in these constructors is very similar.
Many times only the initialization values of the data members is what changes.
One common source of program errors is duplicated code.
So we want to minimize the amount of duplicated code in our programs.
C++ allows us to use delegating constructors.
The idea is that we can now call another constructor of the same class
in the initialization list of constructor.
The syntax is really simple. After the parameter list, we write a colon
and then we follow it with the call to the constructor we wish to call.
Let's see an example with the player class.
Here's the declaration of the player class, as we've used previously.
We've got the three overloaded constructors.
And here's the code for the overloaded constructors using initialization lists.
Notice how similar the initialization lists are.
In this example, the only differences are the values used for initialization.
Rather than write these initializer lists over and over in our code,
we can simply delegate initialization to another constructor. Let me show you how.
In this example, the first constructor is the three argument constructor,
and we use a constructor initialization list as we did previously.
But when we define the no args constructor,
instead of writing another very similar initialization list,
we simply call the three args constructor with the initialization data we need.
We call the constructor by providing the constructor name,
which is the same name as the class followed by the arguments to the constructor.
In this case the no args constructor is the delegating constructor
since it delegates object initialization to another constructor.
In the last example, we do the same thing,
but we delegate to the three arg constructor and provide name val 0 and 0 as arguments.
It's important to note that this only works in the initialization list.
You can't call the other constructors from the body in the delegating constructors.
Also, you can't delegate to another constructor and provide initialization values
to class members.
Let's update the player class in the IDE to support delegating constructors now.
Okay. So we're back in the IDE, and I'm in section 13 workspace
in the DelegatingConstructors project.
So what we've got here is the player class again.
And we've got our same three overloaded constructors.
And what we've got down here from line 21 all the way down to line 32
are our implemented constructors using constructor initialization lists.
As you can see, a lot of this is very duplicated.
So what we're going to do is we're going to refactor this.
So that instead of using constructor initialization list,
we're going to use delegating constructors.
Now what we want to do is, we want to delegate everything in this example
to this 3 args constructor.
So what can we do? Well,
what we can do is we can replace that initializer list with
a delegation. So we can simply say player,
and we'll say none and 0 comma 0.
Okay.
So let me delete the rest of this,
and that's basically it so what's going to happen here is, let me replace that parenthesis with a curly.
So what's gonna happen here is we're gonna call the constructor
from this constructor, that's the whole idea of delegating constructors.
This no args constructor is the delegating constructor now.
So what we're going to do is we're going to call the player constructor
that has those three arguments, which is this guy right here,
the one with the initialization list.
So this guy's really going to do all the work for all of these constructors.
We're simply just going to delegate the work to it.
We'll do the same thing here. We'll call player,
and we'll put that's in name val and 0 comma 0. Again,
and I'll delete the rest of this. And I think i put a parenthesis again,
so I'll replace that with a curly here.
And there we go. So in this case, we're calling
the same idea. We're calling this three arg constructor from here.
Now let's put some output statements in here just to see
exactly how this works in the chaining that takes place.
So what I'm going to do in the body of this constructor here,
I'm simply going to say cout,
and I'm going to say no args constructor.
That's this one.
And we'll have an endline.
And then what I'm going to do is I'm just going to copy and paste that one line of code
into each one of these constructor bodies here.
And in this case, this is the one arg constructor
just expects the one string,
and this guy here expects all three.
So I'll just write three arg.
And that's one arg. Okay.
So that's it. Now we've got our constructors implemented. We're using delegation
here in this context,
and we'll just run our main now.
The idea here is the same -- we're going to create the same objects as we did before we've got
a an empty,
which is a player object,
and that's going to use the no argus constructor, right, because I'm not supplying any information.
So it's going to come up here.
And then rather than
initializing here, we're just simply going to delegate the construction of this object
to the constructor that expects three args, this guy.
Okay. So that's what we're gonna do
and what we'll do is we'll put breaks on all of these constructors so we can see when they're being called.
And we'll also put a break right there.
And let's step through this.
And let's see we've got an error, I'm missing a terminating character.
Okay. I probably have that all set now. Let's try that again. Okay.
So let me put the output window over here so we can see it.
And we'll walk through this. And remember, when we're in the constructors,
we're going to use the this keyword which is really a pointer to the object that I'm creating.
And like i said, I'll talk about that a little bit later in the course.
So we're right here on line 38.
We want to create that empty
object right here. So it's going to call this no args constructor. So let's step through it.
You can see I'm right here now.
Now what we expect is we don't expect this one line of code to execute in the body.
What we expect is to be thrown down here,
right, because that's what I'm doing, I'm delegating. So I'm gonna --
there we go. Now we're at line 32.
This initializer list is going to execute and initialize my object.
That's done. If I look at this,
you'll be able to see none 0 0, which is exactly what I expected.
Now I execute the body of this constructor, so this is going to say three args constructor.
And I spelled constructor wrong but that's okay. I'll fix it when I save the files.
So three args constructor just executed.
Now I'm not done I need to come back to the constructor that called it.
And I'm going to execute this this body right here, no argus constructor. So let's do that.
See we're back now to line 23,
and we execute that one line.
So you can see here that the no args constructor
called the three args constructor which is exactly what we expected.
Okay. So now let's do this this one right here.
I'm creating the frank object, and I'm calling that one arg constructor,
this one right here that expects a string. So let's step through it.
There I am at the initializer.
I'm delegating to the same one here the player
constructor that has the three arguments.
It's initialized. Now I'm going to print out three args constructor again.
Now when I come back here, I still need to execute the body of this constructor,
which I do here. So in this case, the top case, the no args constructor
called the three args constructor.
In this case right now, the one arg constructor called the three args constructor.
Okay. Now we'll basically do this last one right here, the villain.
And for this one, we're just doing this guy directly. We're just running this constructor right here.
It's going to initialize those three values and simply print out three args constructor.
And there's the output, and we're done.
Okay. So that's an example of delegating constructors. It's pretty straightforward.
Many times, you'll have an example. That's really, really simple like this.
And this example will simplify even further in the next video
where we'll use default parameters.
But you can always find a way to use these delegating constructors,
and they're very very handy to use. The nice thing about this
is whatever my initializer is here, and if I've got to run some code.
Remember that if this guy delegates to this guy,
both those bodies are going to be executed.