Analysis of constructor and exception

Source: Internet
Author: User

If an exception occurs in the constructor, allocated resources are not automatically released, for example

~ std::runtime_error(~~= = ~** main( argc,  ** 

The running result is as follows:

Into A constructor

Into D constructor

Into B constructor

Into C constructor

Terminate called after throwing an instance of 'std: runtime_error'

What (): exception from C constructor

Object c throws an exception during the construction process, and the memory space pointed to by pointer B is not released.

How can I release B's memory? First, we can see that c ++ does not call the destructor, because the Destructor does not know how much the object has been constructed, which resources should be released, and which should not be released, of course, the compiler can record this content, but it will seriously affect the efficiency. In addition, in terms of semantics, c ++ believes that the object lifecycle is between the normal end of the constructor and the end of the destructor. The construction of incomplete objects is a non-life thing, it does not exist. You cannot call a destructor for a nonexistent object. By default, the compiler only releases the memory space of Object d. The heap memory pointed to by object B can be released through abnormal display

= = (std::runtime_error &==}

The running result is as follows:

Into A constructor

Into D constructor

Into B constructor

Into C constructor

Into D constructor catch

Into B destructor

Into D destructor

Into A destructor

B is released normally. Let's make another change. Put the constructor B and c in the initialization list and change the constructor D to the following,

D::D() : A(),b( B()),c(

Will it be valid if we continue to use exceptions?

D() :A(), b( B()), c((std::runtime_error &

It looks like very nice. Run it and try again,

Into A constructor

Into B constructor

Into C constructor

Into A destructor

In D constructor catch: exception from C constructor

Into B destructor

Into C destructor

* ** Glibc detected **./a. out: free (): invalid pointer :***

Pointer Error! At the same time, we can find that the base class A executes the Destructor before entering the catch statement, which means that when the catch statement arrives, it has jumped out of the constructor range, members of D and A are no longer accessible.

Why is C ++ unable to access data members in the catch statement of the constructor in vitro?

First, you cannot know whether B and c have been initialized. It is illegal to delete Uninitialized pointers.

Next, let's assume that B is initialized and c is not initialized. We need to delete B. If catch can access B and c (let's make a hypothesis) and change the type of B, to make B contain A * member data, consider this situation,

D() :A(), b( B(static_cast<A*>())), c((std::runtime_error &

A has been analyzed and B's data member A does not exist. This is very dangerous.

C ++ believes that, whether the construction of the base class or data member fails, the entire object structure fails and there is no semi-finished product. The catch statement outside the constructor block (the above one) automatically throws the exception even if it does not display it again until the object construction of the bottom-level derived class stops. For example, in the above example, catch does not display throw. In the main function:

 (std::runtime_error &

The runtime_error thrown by the C constructor is still caught.

To sum up, we can summarize the following rules:

1. the try-catch statement in vitro of the constructor has only one purpose-the exception object captured by the conversion.

2. resources must be allocated in the constructor body, not in the initialization list.

3. You must use the try-catch statement to manage resources in the constructor.

4. Use RAII to manage resources, resulting in fewer brain cells, like this

<B><C> B()), c(

Welcome to discussion

 

Reference

Http://www.gotw.ca/gotw/066.htm

More effective c ++

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.