Why must a base class destructor be accessible only when a custom constructor is declared?

杀马特。学长 韩版系。学妹 提交于 2019-12-02 22:53:04

I suspect that this might be compiler-specific behavior. Here's my theory:

Because (in this particular case) an implicitly-defined T() is a trivial constructor (as defined in 12.1(5) of the standard), the compiler doesn't even attempt to generate a body for T(). Since there's no ctor body, there are no exceptions that could possibly be generated during "construction" (of which there isn't any, really), so there's no need to generate a dtor call, and so no need to generate a dtor body, only to find out that the base class's dtor is private.

But as soon as T() becomes non-trivial (even if it remains implicitly-defined), a ctor body must be generated, and you get the error. Something as simple as adding a member to class T that has a user-defined constructor would make the implicitly-defined T() become non-trivial.

A separate, but related, issue is that new T() doesn't generate a dtor call (since you don't have a corresponding delete anywhere). In contrast, if I just replace new T() with T dummy in your code, then I get the following from gcc, suggesting that it's now doing the full check for dtor accessibility (as a consequence of having to generate a dtor call):

test.cpp: In destructor 'T::~T()':
test.cpp:3: error: 'indestructible_base::~indestructible_base()' is private
test.cpp:7: error: within this context
test.cpp: In function 'int main()':
test.cpp:12: note: synthesized method 'T::~T()' first required here
test.cpp:12: warning: unused variable 'dummy'

Well, if the automatically-generated constructor calls a possibly-throwing constructor, then it will give the same access error.

#include <string>

class indestructible_base
{
  ~indestructible_base();
  std::string s; // <------ this may throw
};

class T : indestructible_base
{
public:
  //T() {}
};

int main(void) { new T(); }

So I guess exceptions is the answer. In ANSI ISO IEC 14882 the only noexcept(true) string constructor is the move constructor. I believe this should compile but ideone says no.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!