Hello, everyone. I'm in the IDE in the section 15 workspace.
And I'm in the challenge project.
And before I go over what the challenge is for this section, I'd
like to go over the account class that has been modified slightly.
And this is the account class hierarchy that we're going
to use for the challenge.
So I'd like to go through it in detail so you understand
exactly what's going on.
It's very very similar to the account class that we've been using along, but
I've made a couple of changes to it.
So why don't we start here at the account class.
You can see I've got my account header file and my
account implementation file.
But let's talk about this account class.
As you can see, there's my class account.
And I've got my overloaded insertion operator, which
allows me to put accounts on a stream really really easily.
Then I've declared these 2 const expressions.
And think of these as constants that are available only to the class.
They're within the class scope.
Sure, we could have defined these outside of class scope,
but then what we do is we pollute the global name space, and we
really don't want to do that.
And the reason we're doing that is because we're providing
default parameter values in the constructor here.
So you can see that we've got default name here as
well as default balance here.
So by using these, I can do it like this, and I can just
change them in one place.
The other option is just to do the constructor like this, just like
we've done before where I supply the default parameter unnamed
account and the balance is 0.
Okay, so again, you could do it either way.
I kind of like doing it this way because it gives me all
my constants in one place.
They are within class scope, and you can decide whether you
want to make them private or protected or public, and you've
really got a lot of flexibility.
So there's my constructor.
And obviously, we've got an account.
In this case, I added the name, right.
The name is a std string a c++ string.
So in this case, what an account is it's got a name
and it's got a balance.
So here's my constructor.
It expects a name and a balance.
If we don't get a name, we get a named account.
If we don't get a balance, we get 0 for the balance.
And at this point, we've got our deposit, withdrawal.
And I just put in a get balance method here which could be handy to use.
I don't think I'm using it in the code, but you may want to use it.
So I've got a deposit method and a withdrawal method, real
basic functionality here, right.
Simply add whatever is given to you to the balance, and withdraw
whatever's given to you the balance assuming that we don't run into a
negative balance when it's over, so just like we've seen before.
Now let's look at the implementation for this.
So we'll look at account cpp.
So here's the account cpp, and it's going to be, again, very, very
familiar implementation I think.
So here you've got your account constructor.
Notice that it expects these 2 parameters, and those guy have
defaults associated with them.
So in this case, this constructor fires, and I'm just setting my
name and my balance to whatever was passed in, real simple constructor.
Here's my deposit method.
It's expecting an amount.
You can see the amount right here.
If the amount is less than 0, I'm returning false.
This is one of the little changes that I made to these methods.
Notice that deposit and withdrawal both return true
false values, right, a Boolean.
So this will return true if the deposit was
successful, false otherwise.
Same here.
This will return true if the withdrawal was
successful, false otherwise.
This is a pretty rudimentary way of doing error checking because
you're just returning true false.
There could be a lot of different reasons for failure.
And we'll talk about that when we talk about exceptions
and exception handling.
But for now, this would serve us just fine.
So here's my deposit method given an amount.
If the amount is less than 0, I'm going to return false because
that really doesn't make sense.
I don't want to deposit negative amounts, which would
be kind of like withdrawals.
If the amount is not less than 0, then I'm simply incrementing
the balance by the amount and returning true, successful.
Here's my withdrawal, same idea.
I'm getting an amount to withdraw.
I'm checking to see if I subtract that from the balance
if I still have a balance.
In which case if I do, I do the withdrawal and I return true.
It was successful.
Otherwise, I return false right here.
All right, here's my get balance, which simply returns the balance.
Notice that's a const method.
And then the very last function down here is my overloaded
insertion operator, which is a friend of this class.
It expects a stream, and it expects an account.
And all it displays is the account, followed by the account name.
Notice that i have access to these guys because I'm a friend.
So all it's displaying is the account name and the account balance.
So hopefully, that makes sense.
You can walk through it and study it a little bit.
Before you start the challenge -- and like I said, I'll explain
the challenge in the next video.
So now let's take a look at our savings account.
We've got 2 classes in this hierarchy.
We've got an account.
We've got a savings account.
So here's my savings account.
And notice that in a savings account is a type of account.
So that's kind of a clue as to what we're going to do, right.
Right here, public inheritance.
So it's an account.
But what it does is it adds an interest rate.
And you can see the interest rate right here.
It's a protected data member.
And the withdrawal is the same as a regular account.
So you can see that the withdraw isn't here, right.
There's no need to override withdraw because the accounts
withdraw works just fine.
It's all we want to do.
We have no specialization for that.
So I commented right here.
Inherits the account withdraw method.
The deposit does specialize.
It's a little bit different.
So the amount supplied to the deposit will be incremented by
the amount I should say here.
Sorry about that.
I will fix that by the amount times the interest
rate divided by 100, right.
So if the interest rate is 5, then that would be 0.05, which is the
5%, times the amount, and we're going to put that right back in.
Okay, that's pretty much it here.
The rest is pretty self-explanatory.
I think I've got 3 const expressions here.
The first one is unnamed savings account, which is my default name.
Notice that it's right here.
If it's not supplied, that's it.
My default balance and my default interest rate are
over here and right here.
Again, you don't have to do this here.
You can simply put them in right in here 0 0 0 0 and unnamed
savings account right here.
This has got to be c++11 to do this kind of thing.
And let's see what else.
What else do we have.
We have the constructor, which expects all 3 of those guys, as I said.
And I've got my deposit, which I have to override to support
this kind of deposit behavior.
Okay, so one of the things that hopefully you'll notice -- and this is
one of the ideas with inheritance is that as you derive classes, you really
should have to do a lot less than the previous class did, right, which
makes sense because after all what we're doing is we're specializing.
We're not redoing.
So let's take a look at the implementation for
the savings account.
You see it's not a lot of code here.
And that's the whole idea.
I mean if you find yourself writing a lot of code in the
specialization classes that you're deriving, then either
it's a really complex derivation or something's not quite right.
So let's take a look at the constructor.
Here you can see the constructor.
It expects a name, a balance and an interest rate.
And remember, a savings account is an account.
So I need to take care of that account part of me.
So right here I'm invoking my base classes constructor.
And I'm passing in name and balance.
Remember, that's what an account has a name and a balance.
So I'm going to let the account class take care of
that, it knows about that.
Those are not my instance variables here.
I'm only putting in the int rate.
Once that's done, I'll come back, and I will initialize the enter
the interest rate to whatever was passed in right over here.
And that'll do it.
Notice that none of these constructors have bodies to them.
Well, I shouldn't say that they do have bodies to them.
You can see the body right here.
There's no code in the body.
You could simply put cout statements in there if you
want to see them execute.
Also there's no destructors, there's no copy constructors, there's no
overloaded assignment operators because we don't need any of those.
The balance is a double.
The interest rate is a double and the name is a std string.
They know how to take care of themselves, so we don't
have to worry about that.
We don't have any raw pointers here.
All right, so now let's take a look at the deposit method.
Here's the deposit method.
You can see we expect an amount to deposit, and we're going to increment
that amount by the amount itself times the interest rate divided by 100,
that's what the business logic says.
Once we know the amount that we want to deposit, it's right
here, then we really don't want to do that ourselves.
We want to ask our account class to do it for us.
So we're going to call the deposit method in the account
class, which is right here.
And you need to put this piece right in front here.
Otherwise, the compiler will call this method right here, and you're going
to end up with recursion forever.
And so be real careful about that.
You want to be sure that you call the account classes deposit
method, and we pass in the amount.
That's it.
And notice something else here.
This returns a Boolean, right.
Well I'm returning whatever my base classes deposit method return to me.
And so if it failed over there, I'm just returning fail here.
If it worked over there, I'm returning true here.
Okay, so again, we're leveraging on the fact that all of these deposit and
withdraw methods will return Booleans.
Notice there is no withdraw method because we're inheriting our parents.
It's public in the account so it's public and me,
so I've got access to it.
And here is the overloaded insertion operator for a savings account.
I mentioned slicing before, if we don't provide this and we pass a
savings account into the account overloaded insertion operator, it'll
slice and this piece here won't print.
It'll still print name and balance because all accounts have names and
balances but this piece here this is what my savings account brings.
So this will just display savings account, the account name, the
account balance and whatever the interest rate is in percent there.
Okay, perfect, so now I wrote a little bit more code just to make
our lives a little easier and it's right in these 2 files right here.
I created 2 files, one is called account underscore util.header
file and an account underscore util implementation file.
And these are utility functions that we're going to use with these classes.
They're not part of the class, they're simply utility functions.
Let's take a look.
Let's take a look at the header file.
Okay, so I've got some simple utility helper functions for the account
class and the savings account class.
You'll see a lot of duplicated code here, a lot of this duplicated
code is going to go away in the next section when we talk
about polymorphic functions.
But here, we're doing everything statically, so
we've got to do it this way.
So take a look at this.
I've got a display function.
I remember, these are regular functions.
These are not class member functions.
These are just plain old global c++ functions.
It's called display, and it expects a vector of accounts, right,
a bunch of accounts, by ref.
Then I've got -- and all that does is just loops through them and displays
each one of them, and I'll show you the code for that in a moment.
These are just the prototypes that we're going to use in main.
Here I've got a deposit.
And all that's going to do is give me a list or a vector, in
this case, of account objects.
And I'm going to deposit this amount into all of them.
So this is going to really be nice for us to test our code.
Same thing here with withdrawal.
Withdrawal a 1000 dollars from all of these accounts that I send you.
So those are the ones for the account class.
These are the ones for the savings account class.
You can see that I've got savings accounts here and accounts here.
Okay, also notice that the names are the same display display, deposit
deposit, withdrawal withdrawal, right.
So we're overloading here.
We're using what we learned a long time ago when we
talked about functions.
We're overloading the functions.
The compiler can tell them apart because of this
first argument right here.
This is a vector of savings accounts.
This is a vector of accounts.
Okay, so let's take a look at some of the code for this.
Like I said, it's a bit long and repetitive, but
hopefully you'll get the idea.
Here's the display.
So if you send me a vector of account objects by reference.
And again, this is const because I don't want to modify it, I'm just
displaying it, then I'm just going to print out this line of counts.
And then I'm going to loop and say use a range-based for loop and for
every account in that vector, I'm just printing it out, just like that.
That's using the overloaded insertion operator.
And that'll display them real nicely.
Here's the deposit.
In this case, I don't want this to be const as we did over there, up top
here because i do want to modify it.
And it's as simple as loop through the accounts for each account
deposit that amount into it.
If it came back true, that means the deposit was successful.
And I just display deposited however much amount to whatever account if.
It fails for whatever reason, I'm just saying failed deposit to this account.
And last method here is the withdrawal, same idea.
I want to withdraw this amount from all of the objects in that vector.
So all I'm going to do is loop through, I'm going to call the
withdrawal method on each account.
And if it comes back true, then the withdrawal was successful,
and I'll display I withdrew a 1000 dollars from each account.
If it fails, I'll say that as well.
Okay, so you can see it's pretty standard.
It's nothing we haven't done before.
The only thing that's different maybe is the organization that we're doing.
So I've got those 3 functions for account, and then I've basically
got the same 3 functions for savings account, you can see
savings accounts right there.
So it's really pretty much the same.
The only difference is that this deposit and this withdrawal right
here will use the specialized versions of the deposit and
withdraw from the savings account.
So that's it.
Let's look at the main.
Here's my main, and it's not that long, but we're going
a lot going on here though.
Notice that I'm including account util.h, right because
i need those utility functions.
And let me scroll up just a little bit, and you can see what's
happening here with the count.
I'm creating a vector.
We've used the vector before.
We'll learn more about the vector and the list and other things when we
talk about the c++ standard template library, but we've used vector so we
should be pretty familiar with it.
So I'm creating a vector here called accounts, a vector of account objects.
And I'm just simply creating an empty account, right.
That's going to be an unnamed account with a 0 balance.
I'm creating another account called Larry with 0, Moe with 22000, and
Curly with 5000, and I'm pushing those accounts at the back of that vector.
So all we're doing there is creating a vector and creating 4 account objects
and putting them in the vector.
Once we're done with that, we're going to use those utility functions.
So you can see this is where it comes in real handy.
Display the accounts, deposit a 1000 into each one of those
accounts, and withdraw 2000 from each one of those accounts.
So that's going to deal with accounts, and then we're going to do the exact
same thing with savings accounts.
So in this case, I've got a vector of savings account objects,
and I'll call it save accounts.
And the same idea, I'm going to create a savings
account object, that's empty.
I'm going to create a savings account object that's superman,
another one for a batman with 2000.
And finally, wonderwoman with 5000 and 5% interest.
Okay, these get the default values for both the balance and the
interest these guys right here.
And this guy gets all 3 default values, right.
It's going to be an unnamed savings account with no
balance and no interest rate.
And then we'll do the same thing with this, display deposit and withdrawal.
You can see that we've got the same code here and here but
different functions will be called because of the overloading.
So let's run this and you'll see the output.
And hopefully, you'll see why i did those utility.
Use those utility functions because it's just going to make
our lives much, much easier and make our main very clear.
So let me run this, build and run.
And here you can see the output.
I'll scroll to the top.
And right here, I'm displaying the accounts.
And this is what you're seeing here on the right side.
Account unnamed account, that's from this guy right here.
Then we see Larry with no balance.
Then we see Moe with 2000.
And then we see Curly with 5000.
Then I call the deposit function.
And what that's going to do is it's going to loop through all
these 4 accounts and deposit a 1000 dollars into each one.
So you can see here I'm deposited all of them returned successful.
So I deposited a 1000 to the unnamed account, and
its balance is now a 1000.
I deposited a 1000 to Larry, he's a 1000.
Moe is now 3000, and curly is 6000.
And then what I'm going to do is I'm going to withdraw 2000
dollars from each one of those accounts as I loop through them.
And I'll scroll this up just a little bit.
And here you can see that right now I'm withdrawing 2000 dollars
from the unnamed account, but the unnamed account only had
a one 1000 dollar balance.
So it failed, and the balance is still a 1000.
I tried to withdraw 2000 dollars from Larry.
Well, Larry only has a 1000.
So that failed as well.
And I tried to withdraw 2000 from Moe and Curly, they have enough balance.
So Moe is now a 1000.
And curly is now 4000.
And now the savings, let me scroll up just a little bit
so you can see it better.
Here now we're doing it with the same thing but with savings accounts.
So I'm creating 4 savings account objects, in this case.
The empty one, superman with 0 0, batman with 2000 and 0, and wonder
woman with 5000 and 5% interest.
And then I'm displaying them.
You can see them being displayed here.
I'm displaying the unnamed savings account 0 0, superman 0
0, batman 2000 0, and then wonder woman 5000 and 5% interest.
Then I'm calling the deposit method for each one of those guys again in
the loop using the utility function.
And what's happening is I'm going to deposit a 1000 dollars
into each one of those accounts.
And notice that I'm depositing a 1000 into unnamed, right.
So now it's got a 1000 balance.
I'm depositing a 1000 into superman.
So it has a 1000.
I'm depositing a 1000 into batman, so it was 2000 up here.
Now it's 3000. Notice it had a 0% interest rate.
So we didn't get that extra little bonus that we want.
But in this case, I'm depositing a 1000 to wonder woman.
And wonder woman has got a 5% interest rate.
So you can see that, that indeed took that into account, so it's really
using that specialized deposit method.
And then what we'll do is we'll withdraw some 2000 dollars from each one of those accounts.
In this case, it's going to fail with the unnamed account
because the unnamed account only has a balance of a 1000.
It's going to fail again with the superman account because it also
only has a balance of a 1000.
But with batman and wonder woman, it'll be just fine because batman
had 3000 and wonder woman had 6050.
So you can see that now we've got a 1000 in batman
and 4050 in wonder woman.
Hopefully, that makes sense, and that gives you an idea of these classes.
Study these, look at them, play with them, run through the debugger,
throw some statements in there.
And what we'll do -- I think you know what we're going to
do we're going to add a few new classes to this hierarchy.
And I'll talk about that in the next video when I talk
about the actual challenge.