用于提升的虚拟析构函数:不可复制的类?

时间:2010-01-12 20:45:25

标签: c++ boost noncopyable

我对以下代码有疑问:

class MyClass : private boost::noncopyable
{
    public:

    MyClass() {}
    virtual ~MyClass() {}
}

class OtherClass : private boost::noncopyable
{
    private:
    MyClass* m_pMyClass;
}

我的想法是MyClass无法使用构造或赋值进行复制。如果我想支持从MyClass派生类,我需要使用虚拟析构函数,我不想支持。我不打算创建指向这个类的指针并传递它们。

我不想要Singleton,我也看不到删除虚拟析构函数的缺点。

如果删除不可复制类的虚拟析构函数,是否会引入潜在问题?是否有更好的实践来处理不需要单例的类,但我只想在另一个类中使用一个实例而不支持继承?

5 个答案:

答案 0 :(得分:13)

不,虚拟析构函数的全部意义在于派生类可以正确地多态破坏。如果这永远不是基类,则不需要它是虚拟的。

答案 1 :(得分:9)

一般规则是,如果您的类具有虚函数,则需要虚拟析构函数。如果它没有,但仍然是从基类派生的,那么基类(以及你的类)可能需要也可能不需要虚拟析构函数。

boost::noncopyable派生你的类并不真正算作是从基类派生的。 boost::noncopyable更像是一个方便的注释,备有几个声明,这些声明将导致编译器强制执行注释。它不是任何传统意义上的基类。没有人会尝试将指向您的类的指针作为指针或boost::noncopyable的引用传递。即使他们做了你的虚拟析构函数也无济于事,因为boost::noncopyable的析构函数不是。

最后,正如评论中指出的那样,你甚至私下继承了boost::noncopyable,所以就课堂外的任何人而言,它根本就不是真正的继承。

所以真的,不需要把它变成虚拟的析构函数。

答案 2 :(得分:3)

我真的不喜欢boost :: noncopyable类作为一个整体。为什么不直接声明类的复制构造函数和赋值运算符是私有的而不是定义它们。这将完成同样的事情,你可以放弃虚拟析构函数。

Boost只提供一个虚拟析构函数,以便人们可以传递boost :: noncopyable对象的多态性,并且仍然可以使它们表现良好。从技术上讲,如果你不打算多态地使用这个类(你甚至可以继承它),你真的不需要虚拟析构函数。

答案 3 :(得分:3)

基类中的虚拟析构函数用于避免部分破坏问题,如:

Base *pBase = new Derived();
delete pBase; 

//if destructor is not made virtual then derived class destructor will never called.

当您私有地继承一个类时,编译器不会执行从派生到基类的隐式转换,如果您确定派生对象永远不会使用基类指针进行破坏,那么您在基类中不需要虚拟析构函数。 / p>

Base *pBase = new Derived(); // will flash error 

答案 4 :(得分:1)

boost::noncopyable意味着您不想要制作对象的副本。您知道这与从对象派生的不同。

如果您不能从对象派生,那么摆脱虚拟析构函数是完全正确的。如果要强制执行“不从此对象派生”策略there is a way。不幸的是,没有boost::nonderivable可以帮你解决这个问题。


如链接中所述,C ++ 11允许您声明类final

class MyClass : final private boost::noncopyable { ... };