In this course, we will discuss the topic of exceptions and debugging. We'll see that exceptions are objects representing exceptional situations and that these are usually problems in our code or in the environment in which our code is running. By using exception handling, we will know how to respond to problems when they arise.
- Learn the proper syntax and techniques to work with exceptions
- Understand inheritance in the context of Object-Oriented Programming
- Beginner coders, new to C++
- Developers looking to upskill by adding C++ to their CV
- College students and anyone studying C++
To get the most out of this course, you should have a basic understanding of the fundamentals of C++.
In the last lecture, we discussed the basics of exceptions. We learned that exceptions are reactions to errors that occur in our programs. We also learned that we can handle exceptions, meaning when an exception occurs, when it comes into existence, we say the exception was thrown and we can make a determination about how our program should respond to it. We also discussed how the exception class is the ancestor of all the built-in and often used to define exceptions in C++. Two of these built-in exception types and children of the exception class are logic error and a runtime error. In this lecture, we will cover what logic errors are and discuss the logic error class specifically. In general, the term logic error refers to an error that generally results from a fault and logic in the code. These types of errors include our out of range error that we saw in the previous lecture. They can be solved using better coding practices such as in our earlier example, simply not try to access elements outside the allocated memory for our vector. Let's consider one of the derived classes of logic error called length_error. This type of error occurs in situations involving invalid lengths, such as trying to create a vector of a size greater than the maximum length allowed for vectors. So, let's create a project named LogicErrorFun and write some code. All right, empty project LogicErrorFun. Just a minute, and we will create our main file here, main.cpp. Awesome. So, we don't want to forget the vector and the stdexcept libraries either in addition to our iostreams. So, vector and stdexcept namespace standard int main and return 0. Awesome. So, vector<int> called myNums and we're going to do it without exception handling first. So, myNums.resize. So, we're taking this vector that has whatever default size is and then we're telling it, I want you to take the maximum size for vectors and then we add one to it to tell it to try to go larger than that. So, this is how we're going to generate this exception. So, I'm going to put, "Yay, it's a big vector" right here. Okay, now let's run this with the debugger. So, debug and then start with debugging or start debugging. All right, so we'll see that we have more information than we would have had if we had not run with the debugger. The debugger stops where the error occurs in this case. Although this isn't always the case and in fact it probably isn't usually the case, especially for really complicated exceptions. The debugger is an invaluable tool for finding where the errors are. We are trying to resize our array to be bigger than the maximum allowable size for vectors of integers. This is why we get a length error. Given the material we covered in the previous lecture in the example code you can see part of right now, you should be able to handle the length error that we're getting using a try-catch statement. So, of course I'm issuing you a challenge. That's right. Given our current code and the knowledge you gained from the last lecture and this one, I'd like you to handle this length error that is currently causing our program to crash. Don't change the vector sizing to less than its max which is probably what you want to do in reality. But we're focused on exceptions now. So, I want you to print out the error to the console using the what method just like we did before. But this time we're handling a length error instead of an out-of-range error. Make sure you have stopped the debugging from our last run before you proceed . That requires us to go to debug and then stop debugging. Good. So, pause the video and come back when you're done or if you need some help and don't forget to test your program to make sure that it works. How'd that go for you? Were you able to extrapolate the solution based on what you learned in this lecture and the last using the code? That's great if you are able to complete this challenge. Applying knowledge as you proceed through the course is important. We are building up our understanding and skill both in terms of problem solving and in terms of syntax specific to C++. So, let's code this together. So, we need to put a try catch around where the critical area of our code is or the area that could cause the exception. Now we know right away that this is going to be this resize right here. Now obviously in reality you'd know how to fix this by not having it go out of balance, but again we're trying to generate an exception, so we see how it works. And you probably were able to use the syntax that was on the screen from the last project that we worked on, the Visual Studio Project, rather that showed you how we could use the exception for out-of-range and you just ported it over to use length error. So, now we have to print out again the what and you're not restricted to just doing this. You can do whatever you want pretty much inside the catch and sometimes you might say okay, I know a way to recover from this. So, you might say instead of that, resize that failed, let's try resizing it to the max size. So, that would maybe be a reasonable way to accommodate what the user wanted. And of course, let's run it. Start without debugging. All right, good. So, instead of crashing, we do have a more graceful way of letting the user down saying that the vector is too long. So, they tried to resize it to weigh too big or a little too big in this case. So, obviously, again you could do a lot of other things inside the catch as a response to the error. In our case, we just printed a message containing the error data from the exception to the standard output. One important note about syntax that you might see is when we deal with exception handling, you may see someone use cerr, C-E-R-R object instead of the cout object. In other words they use the standard error object instead of the standard output object. By default, these both direct their output to the console. However, if someone wanted to redirect errors to a different place than the console, cerr gives them the ability to do that without affecting cout and console output for standard output. So, it keeps the errors separate from the standard output. For our purposes, this isn't a big deal but I did want to make sure you knew this in case you came across that object or asked to use it. So, let's change our code and rerun it just to see what it looks like. So, the error could go to cerr which is also available in iostream. So, it's just a different object and by default these two reference the same things. But you can actually set it so that they reference different things. All right, there you go. Same output as we expected. Same output as before. All right. That was a lot of fun. I hope you enjoyed learning about the basics of logic errors in this lecture. In the next lecture, we will discuss errors that aren't as easy to fix by just using good coding practices and instead are much better suited for exceptions. These exceptions are called runtime errors. Let's check that out next. I'll see you there.