Why does the destructor run twice in C ++?

In fulfilling my programming assignments, I seem to stumble on the basic C ++ concepts. I found an error in my program, and this was caused by the fact that my destructor works more times than I expected. Here is a sample code demonstrating what I'm doing wrong, down to simple things.

#include <iostream> using namespace std; class A { public: A(int num) { number = num; cout << "A constructed with number " << number << ".\n"; } ~A() { cout << "A destructed with number " << number << ".\n"; } private: int number; }; class B { public: B(A pa) : a(pa) { cout << "B constructor run.\n"; } ~B() { cout << "B destructor run.\n"; } private: A a; }; int main() { A foo(7); { B bar(foo); } //Pause the program. system("pause"); } 

What I expect will be A foo(7); allocates stack space for an object A named foo and calls the constructor, passing 7 . It assigns 7 number and displays a result indicating that the constructor has run. Now B bar(foo); allocates stack space for an object B named bar and calls the constructor, passing foo by value, which is just a container for int . The constructor assigns the parameter A , passed to it, to its private data member A and displays the result.

Now, when bar goes out of scope in a closing brace, I expect the bar destructor to be called, which displays the result on the screen and then calls the destructor for its data members, namely A a . This destructor displays the output and discards the int number that it contained.

The result is expected to be as follows:

 A constructed with number 7. B constructor run. B destructor run. A destructed with number 7. //Destructors should be called in the reverse order of their construction right? 

Actual conclusion:

 A constructed with number 7. B constructor run. A destructed with number 7. //This is unexpected. B destructor run. A destructed with number 7. 

What causes additional destruction?

+4
source share
4 answers

Obviously, this comes from the data of the element A a; of class B. I suppose you doubt that why not see any construction inference from A because it was constructed using the default copy-ctor for class A. It is better to add one instance-ctor for class A so that you see the design procedure.

 A(const A& a) { number = a.number; cout << "A copy-constructed with number " << number << ".\n"; } 
+1
source

Constructor B takes object A by value, which means that foo copied to pa , which is then copied to member A The compiler was able to strip one of the copies (an argument to the constructor), but the other cannot be deleted, and you have a second object A , which will be destroyed.

+2
source

I hate it when people get pretty "foo" and "bar".

But I see two instances of "A" being built - one explicitly, the other - implicitly "B". And two destructors are called.

What do not like in this picture;)?

+1
source

because class B has one element A a therefore, to destroy object B, you first need to call the destructor of its member.

0
source

Source: https://habr.com/ru/post/1415883/


All Articles