在派生类中将公共父析构函数设为私有

Posted

技术标签:

【中文标题】在派生类中将公共父析构函数设为私有【英文标题】:Making public parent destructor private in derived class 【发布时间】:2019-12-03 16:39:12 【问题描述】:

当我尝试编译以下代码时:

class A 
public:
    A();
    ~A();
;

class B : A 
private:
    using A::A;
    using A::~A;
;

我收到以下编译器错误消息:

error: 'A::~A' names destructor

为什么会这样?

我想这样做的更大原因是能够使用模板来创建一个容器,该容器理论上可以通过容器 实例化来存储任何类型(它也定义了 Node 类),但想使通过创建一个名为 C_Node 的容器的派生版本,该容器具有除 Node 类私有之外的所有内容,从而减少了用户的困惑。最终目标是允许用户声明容器 C,然后通过向上转换将 C_Node 推入 C。

如果在 C++ 中有更好的方法,请告诉我。

【问题讨论】:

你不能继承析构函数。除非您手动进行某种资源获取,否则您永远不需要编写析构函数。 C++ 提供std::vectorstd::shared_ptr 和(如果需要)std::enable_shared_from_this。这些不能用来解决问题吗? 内森奥利弗:好的;我想这是一个公平的假设,一旦我获得更多的编码经验。谢谢。 Elijay:Vector 只允许你存储一种类型的对象,但我希望能够灵活地存储更多。我还没有听说过其他功能,但我认为我现在已经足够了。谢谢。 【参考方案1】:

这不是一个存在的功能,也没有任何意义。

using A::A 不继承基本构造函数。它在该位置合成一个B(A's args),并使用该访问级别,将其参数转发给基本ctor。

析构函数没有参数,所以没有这个特性。 可以添加了吗?当然。但没有真正的理由这样做。

你可以简单地写 ~B() = default; 来获得你想要的效果,但我强烈建议不要将析构函数设为私有。

【讨论】:

是的,我认为这是“标准委员会”做出的决定,但幸运的是,它仍然没问题,因为似乎很少将析构函数明确称为一般行为准则。跨度> 即使他们是,这是一个低级别的操作,你不应该竭尽全力去阻止。【参考方案2】:

几乎在所有情况下,您都不应该将析构函数设为私有。析构函数需要是公共的,以便编译器可以在对象到达其生命周期结束时调用它。也没有理由尝试“隐藏”基类的析构函数。

任何人都不应该显式调用析构函数,除非在非常低级的代码中,例如使用原始联合的那种。

你见过std::any 类吗? std::any 是一个可以存储任何类型的类,我认为它可以满足您的要求:

// main.cpp
#include <any>
#include <iostream>
#include <string>

int main() 
    using std::any;
    using std::string; 

    any x = 10;
    // x can be assigned any type
    x = string("hello");

    // You can get the type x contains safely using any_cast
    std::cout << std::any_cast<string>(x) << '\n';

std::any 是在 2017 年推出的 C++17 语言中添加的。您可以通过在 gcc 或 clang 上添加编译标志 -std=c++17 来使用它!

$ g++ -std=c++17 main.cpp -o main

【讨论】:

我会介绍一下 库。谢谢。

以上是关于在派生类中将公共父析构函数设为私有的主要内容,如果未能解决你的问题,请参考以下文章

在一个派生类对象结束其生命周期时析构函数的调用顺序

C++ 析构函数:无法访问类中声明的私有成员

虚析构函数与纯虚函数

《面向对象程序设计》高手进~~~~~~~~~~~~!!

虚析构函数

使用使析构函数私有[重复]