In the general design of the program, how can we determine that a method is suitable for execution as expected? In the C language, returning an integer is a common method, such as a-1, for example, if a file is opened in Linux and-1 is returned if the file fails to be opened, if everyone complies with the rules, it will still fail if 0 is returned. In Java, exceptions are forcibly used for exception handling. In C ++, they are not. You can never use them at all. To be honest, I am very good at using them. Sometimes I forget it, the most commonly used is the C style, which is not superior or inferior to the exception handling style. C is simple and clear. C ++ exceptions can contain more information to facilitate log and debugging.
Exception classes are defined in the standard library, but they are only framework-level. In actual use, if you are sure to use exception handling for Exception error handling, you need to expand on the standard library, or recreate the wheel on your own.
Today, I won't talk about using the exception syntax in C ++, but I just want to pay attention to it.
1. An exception is thrown in the constructor.
If an exception is thrown in the constructor, it indicates that the object is not constructed successfully. Therefore, the well-designed destructor may not be called, if you use some resources in the constructor before throwing them out, you must manually release them.
For example:
A: A () {P = new int [10]; // The above memory allocation is complete, and then you throw an exception} ::~ A () {Delete [] P ;}
2. The Destructor cannot throw an exception and solve the problem internally.
Destructor are a rare way to manage resources. In any case, make sure it is fully executed.
In the grass-roots system, you may worry about throwing an exception in the subclass destructor. Will the destructor of the parent class still be called? Let's take a look at the sequence of class construction. We only talk about the generated during the construction, and the static keyword will not talk about it.
The following code example:
# Ifndef super_hpp # define super_hpp # include <iostream>/*** @ brief the super class superclass parent class */class super {public: Super () {STD :: cout <"Super \ n";} virtual ~ Super () {STD: cout <"Super destructor \ n" ;};# endif // super_hpp # ifndef sub_hpp # define sub_hpp # include "super. HPP "Class A {public: A () {STD: cout <" A \ n ";} virtual ~ A () {STD: cout <"A destructor \ n" ;}};/*** @ brief the sub class subclass */class sub: public super {public: Sub (): Super () {STD: cout <"SUB \ n";} virtual ~ Sub () {Throw 1; STD: cout <"sub destructor \ n";} protected: Private: A ;};# endif // sub_hpp
#include "sub.hpp"int main(){ Sub *s = new Sub(); try { delete s; }catch(int i) { std::cout << i << std::endl; }}
As shown in the result, the parent class is constructed first, and then the data member then calls the constructor. C ++ will ensure that the fully constructed object calls its destructor, so the previous constructor in a hierarchical class throws an exception. However, the Destructor that throws an exception will not be called completely. For example, if one sentence is output less, a resource release operation may cause leakage.