下面的这个例子说明了如何防止派生类被复制。它基于一个基类,其中复制构造函数和复制赋值运算符都被声明为 private
。
class Uncopyable
{
protected:
// allow construction and destruction of derived objects...
Uncopyable() {}
~Uncopyable() {}
private:
// but prevent copying...
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
我们可以使用这个类,结合私有(private)继承,使类不可复制:
class derived: private Uncopyable
{...};
请注意类 Uncopyable
中的析构函数未声明为 virtual。
我以前学过
- 基类中的析构函数应该是
虚拟的
。 - 不应将非基类中的析构函数设为
virtual
。
在此示例中,Uncopyable
的析构函数不是virtual
,但它是从中继承的。这似乎与我之前学到的智慧背道而驰。
何时以及为何不应将基类中的析构函数定义为virtual
?
最佳答案
如果您可能尝试通过基类型的指针释放派生类型的对象,则基类析构函数只需要是虚
。因此,如果您仅私有(private)地而不是公开地继承基类,就像Uncopyable
中的情况一样,那么您不需要担心放入一个virtual
析构函数,因为当使用私有(private)继承时,您无法获得指向派生对象的指针并将其存储在指向基类型的指针中。
另一个例子可能是,如果你要使用像这样的混合类,它使一个类跟踪对象分配的数量,其中混合类继承自以获取行为但不进行多态处理:
template <typename T> class Counter {
public:
Counter() { ++numInstances; }
Counter(const Counter&) { ++numInstances );
~Counter() { --numInstances; }
static unsigned getNumInstances() { return numInstances; }
private:
static unsigned numInstances;
}
template <typename T> unsigned Counter<T>::numInstances = 0;
更一般地说,当使用静态多态性时,您不需要虚拟析构函数,因为您永远不会使用指向基类型的指针以多态方式处理类。您仅使用指向派生类型的指针。
可能还有一些其他情况我没有在这里介绍,但这两个(私有(private)继承、mixin 类和静态多态性)涵盖了不需要虚拟析构函数的大部分空间。
关于c++ - 什么时候以及为什么不应该将基类中的析构函数定义为虚拟的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7005084/