抽象基类中的析构函数保护不会在 C++ 中继承
Destructor protection in abstract base class is not inherited in C++?
我在代码中发现了内存泄漏,这是由于仅调用对象的基类析构函数引起的。这个问题是可以理解的:我已经将virtual
添加到接口类MyÌnterface
的析构函数中。令我困惑的是,编译器显然为我的帮助程序类创建了一个标准析构函数,MyHelper
最终被调用。我用两个不同的编译器尝试了这个。
这让我非常惊讶,因为我观察到,如果成员或基类引入限制,则不会创建大多数默认实现。为什么析构函数的保护不是继承的?
#include <iostream>
class MyInterface
{
public:
virtual void doSomethingUseful()=0;
// a lot more functions declared omitted
virtual void doSomethingElse()=0;
virtual void doSomethingIndividual()=0;
protected:
/// protected destructor to forbid calling it on interfaces
~MyInterface() {} // HERE the virtual is clearly missing
};
/// a common base that defaults most functions implementations
class MyHelper: public MyInterface
{
public:
void doSomethingUseful() {}
// a lot more default implementations omitted
void doSomethingElse() {}
};
class SomeImplementation: public MyHelper
{
public:
SomeImplementation()
{
std::cout << "SomeImplementation ctr" << std::endl;
}
~SomeImplementation()
{
std::cout << "SomeImplementation dtr" << std::endl;
}
void doSomethingIndividual()
{
std::cout << "SomeImplementation did it." << std::endl;
}
};
/// user of MyInterface cannot delete object mi passed as parameter
int deleteSafeUsage(MyInterface& mi)
{
mi.doSomethingIndividual();
// would cause a compiler error: delete &mi;
}
/// usage restricted to MyHelper level, only exception is object creation
int testIt()
{
MyHelper* h = new SomeImplementation;
deleteSafeUsage(*h);
delete h; // <- HERE the memory leak happens!
}
这里是上面示例代码的输出,它"显示"了缺失的SomeImplementation ctr
:
SomeImplementation ctr
SomeImplementation did it.
构造
函数和析构函数不是继承的。那么,为什么它们的知名度会被继承呢?
你可能想检查标准以确保,但 cpp偏好是这样说的,强调我的:
如果没有为类类型(结构、类或联合)提供用户定义的析构函数,编译器将始终将析构函数声明为其类的内联公共成员。
因此,如果您希望~MyHelper
受到保护,则必须明确声明它。
请注意,如果MyInterface
有一个虚拟析构函数,则MyHelper
的隐式析构函数也将是虚拟的。所以这方面是遗传的,有点。同样,如果您想确定,您需要咨询标准,但这在 c++ FAQ lite 中提到
为了完整起见,以下是 Herb Sutters 关于如何使用一般虚拟性和析构函数的指南。
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- C++继承更改成员
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 关于C++中具有多重继承"this"指针的说明
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 如何在QT Creator上将QWidget声明为继承类的对象