Why does a derived constructor need a basic destructor?

class A{ public: A(); private: ~A(); }; class B:public A{ public: B(){}; private: ~B(); }; int main() { return 0; } 

I have a compilation error:

 test.cpp: In constructor 'B::B()': test.cpp:5:4: error: 'A::~A()' is private test.cpp:10:8: error: within this context 

I know that the derived constructor needs to call the base destructor, so I set A::A() as public . However, why does the compiler complain that it needs public A::~A() ?

+5
source share
3 answers

The closest specification I could find is here 12.4.10 class.dtor :

... A program is poorly formed if an object of type or array of a class is declared and the destructor for the class is not available at the declaration point.

class B cannot access private: ~A() , but implicitly declares class A because it is a base class (this is almost the same as declaring the first member variable - except for optimizing an empty base).

I am not a language lawyer, not a native speaker , but an invalid base class destructor seems to be a problem, and the above may explain why the error points to the B() constructor (the compiler can perform checks when they are really needed, and not earlier )

The destructor ~A() must be made at least protected or B friend A

+4
source

Report on the defect of the working group of the main committee on C ++ 1424 standards (submitted by Daniel Krugler in 2011-12-07):

The current specification does not seem to indicate whether an implementation is allowed / mandatory / forbidden when a sub-object destructor is unavailable.

This is fixed in C ++ 14 by adding the concept of a potential call to a destructor. The current draft standard section 12.6.2 (10) states:

In the constructor without delegation, a descriptor is potentially called for each direct or virtual base class and for each non-static data element of the class type (12.4).

[Note. This condition ensures that destructors can be called for fully constructed sub-objects in the event of an exception (15.2). -end note]

And in 12.4 (11) :

A destructor is potentially called if it is called or specified in 5.3.4 and 12.6.2. A program is poorly formed if a destructor that is potentially called is deleted or inaccessible from the call context.

+3
source

Declare the constructor and destructor as public (the constructor of the base class and the descriptor can be protected if you make sure that it is called only by subclasses). When building subclasses have an instance of the base class created as cubobject, an explicit or implicit call to the constructor and destructor is performed

0
source

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


All Articles