[英]How do you implement the destructor in CRTP?
实现奇怪的重复模板模式(CRTP)时,是否需要析构函数是虚拟的? 如果不是,那么正确的非虚拟实现是什么?
我将提供一个示例,希望可以使事情变得更轻松:
template<typename T>
class Base
{
public:
virtual ~Base()
{
// Should this be virtual? Non-virtual?
std::cout << "Base::~Base()\n";
}
};
class Derived : public Base<Derived>
{
public:
~Derived() override
{
std::cout << "Derived::~Derived()\n";
}
};
int main()
{
Base<Derived>* b = new Derived;
delete b;
}
结果:
Derived::~Derived()
Base::~Base()
( 这里有现场样本 )
编辑:更新了示例以使用运行时多态性,以便需要虚拟析构函数进行适当的清理。
从这个意义上说,CRTP基类与任何其他基类没有什么不同。 仅当要通过指向Base<Derived>
的指针delete
Derived
类型的对象时,才需要虚拟析构函数。 否则,不需要虚拟析构函数。
Base<Derived>* b = new Derived;
delete b; // Base<Derived>::~Base<Derived> must be virtual
在您显示的示例中,不需要虚拟析构函数。 仅当您可能需要使用指向基类的指针来调用虚拟析构函数时,才需要虚拟析构函数,在这种情况下,与重写函数一样,它必须是虚拟的。 而且,对于您所显示的CRTP类,几乎不需要删除Base<T>
而不是T
本身。
int main()
{
Derived *a = new Derived();
// we have the right type anyway, so dont actually need a virtual anything (even normal virtual methods)
delete a;
Derived *a = new Dervied();
Base<Derived> *b = a;
// We are now deleting via a parent class, so this needs a virtual destructor.
// This is pretty uncommon with a simple CRTP however.
delete b;
}
如果要在指向派生对象的基类的指针上调用delete
,则需要一个虚拟析构函数,这就是它的全部。 CRTP或没有CRTP。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.