Welcome back. We're in the last part of the solution to the challenge for section 16.
The only thing we've got left to do is clean up those account util files,
so that we don't have all this duplicated code.
So I'm in the challenge solution project.
And this challenge solution project right now is exactly like we left off part 2.
So the first thing we want to do is we want to look at these helper functions,
and we really want to get rid of all of them except what we absolutely need.
And what we absolutely do need is, remember, we're going to come at these things now with
base class pointers,
so that way we can just use dynamic binding and only have one version of them.
So that's what we're going to do. We're going to keep display deposit and withdraw.
But instead of having a vector of account objects, we're going to have a vector of
pointers to account objects.
That's my base class pointer. That's what really gives me the power of dynamic polymorphism.
So that's what I need to do.
All of these down here I can get rid of.
I don't need specialized versions of these things because the whole point of
dynamic polymorphism is to let the runtime system figure out
which one to use.
So this is what we want to reduce it to.
I'm going to modify that to say pointer classes because that's really what we are
and also these include files. Notice that the only thing we really care about is account,
so we don't need all these include files, we can get rid of them. We only need the account.
Okay. So that's where we're at now.
Now the implementation for all of those functions, let's go to that file.
So in the account util cpp file,
we only want to keep the first three, and we're going to modify them slightly.
The rest of them we can
just get rid of because those are the specialized versions for savings, checking account and trust account.
And those were assuming static binding. So we're not doing static binding anymore, so we don't need them at all.
So let's get rid of them.
And this is what I've got now. I've got three functions:display,
deposit and withdraw.
Now we do need to modify them slightly because our prototypes now expect
pointers right here.
So that's a pointer,
and I'm just going to say account object pointers because that's really what we are.
So let's take a look at this for a second and understand what's going on here.
In this case, I've got for const, auto.
There's my account, right. Now this is -- this needs to change a little bit
because I don't really want a reference. I already have a pointer,
so I don't need that at all. I just need to get rid of that.
And then now since auto will be a pointer, I just need to de-reference the pointer here.
That's an object, and that will call the overloaded operator
that we just created,the insertion operator.
So that's just a really precise change, but that's all we need to do here.
The same with deposit. In deposit, we've got account pointers again,
so we'll change that because the vector is a little different.
And we don't need the reference here because we've got a pointer.
But what do we do now.
Well, we've got to call the deposit method right, but we have a pointer, so we just need to change the operator
to the arrow operator.
That's it.
And then here with withdraw, last step,
again,we've got pointers to accounts in the vector.
So what do we do here, same idea. Get rid of the reference because we've got pointers there,
and we call account withdraw from the pointer.
We also need to make a couple of changes right here.
We need to dereference that pointer to get the account here as well,
that will also call the overloaded insertion operator.
We need to dereference the pointer here to get the object and here as well.
And that should do it. You can see how much
code we got rid of. We got rid of a ton of code,
and we've simplified our project, we've simplified our thinking.
We can come at these now with base class pointers
and let the runtime system figure out which method to bind.
All right. So now let's go to our main and take a look.
Here's our main. There's a whole bunch of stuff in here. Let's give it a run and see what happens.
There we go. There's our run. You can see here I'm creating a checking account.
Again, this is not a pointer, so this is just creating a plain object on the stack.
Frank with 5000, there it is.
Now I'm creating a trust account, and I'm creating that account dynamically
through a base class pointer. And there's James.
No balance, no interest and no withdrawals.
And notice how we were able to print that
on the stream just because we're using our overloaded operators and it's printing it correctly.
Now we're creating Larry, Moe, and Curly as three pointers to accounts.
And again,
we're create -- we're instantiating a checking account, a savings account and a trust account.
And then we're adding those three pointers to this vector accounts.
Now we're calling display accounts, that's that function that we just
updated in the account util.
And it's going to display the three accounts, and I expect dynamic binding.
That's exactly what happens. You can see right here:
checking, savings and trust. That's, pretty cool.
Then we deposit a 1000 dollars into each one of those accounts. You can see right here
I'm depositing a 1000 to checking, to savings and to trust.
Finally, we're withdrawing 2000,
that's this code right here. You can see the last one fails because there's not enough balance.
And then finally, we display the accounts one last time, and we see the balances.
We clean up our pointers, and we're done. Now we're done.
The challenge is over. I hope you had a fun time doing it.
If you had trouble with it, don't worry.
This was not an easy challenge. This was a very, very challenging exercise.
Go back and understand what I did compared to what you did.
Maybe you just forgot to dereference a pointer and it was as simple as that.
For example, if you're in the account util cpp file,
and if we forgot to de-reference these pointers right here,
let's just do the withdraw, and you'll see the difference when I run this again,
you'll see the difference when I run this again.
Look what prints out here on the withdrawal, right. There you see that.
That's the pointers. Those are the addresses.
So that's a clue, right. I'm printing the pointer.
Oh of course, I'm printing the pointer. I don't want to print the pointer.
I want to print one it's pointing to. So that's where you have to go back here,
and now dereference that pointer and get what it's pointing to,
and that'll get you exactly what you got.
All right. So congratulations on finishing this section. This was a very complex section.
And this really takes your c++ knowledge to another level.
What we'll do in the next section is we'll talk about smart pointers,
and we'll be able to finally get rid of all these raw pointers.
In modern c++, we need to understand raw pointers.
We must understand raw pointers,
but we really want to develop using smart pointers
and never ever having to worry about de-allocating storage with delete.