In this video, I'd like to briefly talk about exceptions in the context of
c++ class.
Exceptions can be thrown from class methods,
constructors and destructors.
Let's talk about the last one first.
Do not throw exceptions from a destructor.
The destructor is marked in c++ as no except by default,
which means that it does not throw exceptions.
If a destructor is called as a result of an exception being thrown elsewhere
and then the destructor throws an exception,
then there's a problem since the original catch block will never be reached.
This is a very bad situation.
The only time a destructor might throw an exception
is if it handles it itself, and that's a very unlikely use case.
So remember, best practice is to not throw exceptions from a destructor.
Okay. So now let's talk about methods and constructors.
In the case of class methods,
exception handling here works just as we've seen with regular functions.
What about constructors?
Constructors could certainly fail.
And since constructors don't return values, we can't return a Boolean or an error code.
Constructors may fail for many reasons. For example, suppose you're allocating
memory dynamically and you're unable to allocate
it or if you open a file in the constructor but the file doesn't exist.
In cases such as these, the constructor can throw an exception.
The rest works just as you would expect.
Let's see an example of throwing an exception from a constructor.
In this slide, we're using the account classes that we've been using throughout the course.
Suppose we cannot have accounts with negative balances.
So in the account class constructor,
we can check the balance and if it's less than 0,
throw an illegal balance exception object.
In this case, we're assuming that we've created our own illegal balance exception class.
That's it. Now let's see how we can catch this exception if it occurs.
So here we have a try block. And in that try block, we're declaring a unique pointer to an account object.
And using make unique to create a checking account object for Moe
with a negative balance on the heap.
Since the account balance is negative,
the account constructor is going to throw an illegal balance exception,
which we're catching in our catch block.
We display an error, and our program continues.
Now there's a lot more to class level exceptions.
But for the purpose of this course, this is the basic information necessary to use
and understand class level exceptions.
In the next video, we'll look at the exception class hierarchy that the c++
standard library uses internally,
and we'll see how we can tap into that hierarchy for our own exception classes.
But first, let's head over to the IDE and let's throw a class level exception
from our account class.
Welcome back. I'm in the IDE, and I'm in the still in the section 18 workspace,
and I'm in the ConstructorException project.
And what I've done here is I've copied all those files
that we created for the account class that we've been using throughout the term.
So I've got accounts and checking accounts and printables
and basically, everything we've done, this is the latest version of it.
But what I've done is I've added a new
header file right here called illegal balance exception.
And i don't need the cpp file because everything can be done in this header file.
Notice what I've done here. I've created a class called illegal balance exception,
which represents the condition where we've got an illegal balance, in this case,
a negative value.
This is the exception object we're going to throw.
And then we've got a constructor and a destructor.
And I've tagged them both as default that way we're using just regular default constructor
and regular default destructor. That's it.
Now what we want to do is go to our account cpp file.
And what we're going to do is in the account constructor right here
we're going to check to see if the balance is less than 0.
If the balance is negative, then we're going to throw in an illegal balance exception.
That's that class that we just created. This will throw an object of that class.
Okay.
Now I mentioned that there was a lot more to constructor level
exception handling.
One of the things that you can do with constructors is you can try
remember we have an initializer list here.
We could try to execute some of that.
So it's possible to put try statements in there as well.
In this case, we wouldn't do that, but you might want to do that in subclasses.
Again, that's a little bit beyond the scope of the class, but I just wanted to bring it to your attention
in case you see that out there.
So this is it here, right. We've got an account. If the balance is negative, we're going to throw an exception.
So now let's look at our main and let's test this out.
So here's my main. And notice what I've done in the main.
I've got a try block right here. Let me grab my pen so I can mark this up
and make it a little clearer.
I've got a try block right here. And in the try block,
I've got a unique pointer to the base class.
I call it Moe's account.
And I'm using std make unique to create a checking account on the heap.
That checking account contains the name Moe
and notice that negative balance right there.
Okay. That's going to throw an exception. We're using this in the try block
because that constructor for the account class. In this case, remember, it's checking account,
but it's calling the base class constructor as well. And that's the guy that's going to throw the exception
So in this case, this will throw an exception.
It'll throw a illegal balance exception which I'm catching here
by const ref.
If it doesn't throw an exception, then we simply de-reference Moe's account and print
it out to stand it out.
Okay. If it does throw an exception, we're going to catch it right here.
And we're going to deal with it. How do we deal with it? We're just going to say couldn't create account, negative balance.
That's it. But the point is our program completes successfully. This will execute.
It doesn't crash. Okay. Now let's do this two different ways.
Let's run this test case. And first, let's create it with a positive balance,
a 10 dollar balance.So let me build and run,
and the output says checking account Moe 10 dollars,
program completed successfully, just what we'd expect.
But now let's create the negative balance, and we'll build and run again.
And notice the output now says couldn't create account negative balance.
And again, program completed successfully. That's pretty cool.
So that works really, really well. And that pretty much does it.
For the section challenge in this section, it's actually a pretty easy challenge.
Although some of the things will be a little bit advanced, the challenge is pretty easy to do.
What I'd like you to do for that challenge, and I'll talk about it in the challenge video
is to provide an exception
when we've got insufficient funds. Okay. Remember, before we created
right here this withdrawal that was true false.
Well, rather than do true false, let's throw an exception and catch it,
but we'll get to that soon.
In the next video, we'll talk about the c++ standard exception class hierarchy.