8

我对以下代码有疑问:

class MyClass : private boost::noncopyable
{
    public:

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

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

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

我不想要一个单例,我看不出删除虚拟析构函数的不利之处。

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

4

5 回答 5

13

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

于 2010-01-12T20:49:28.153 回答
9

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

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

最后,正如评论中指出的那样,您甚至是从私有继承的,boost::noncopyable因此就类外的任何人而言,它甚至都不是真正的继承。

所以真的,没有必要让它成为一个虚拟析构函数。

于 2010-01-12T21:04:13.240 回答
3

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

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

于 2010-01-12T20:51:07.417 回答
3

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

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

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

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

Base *pBase = new Derived(); // will flash error 
于 2010-01-12T21:09:10.077 回答
1

boost::noncopyable意思是说您不希望制作对象的副本。您知道这与从对象派生不同。

如果您永远不会从对象派生,那么摆脱虚拟析构函数是非常好的。如果你想强制执行“不从这个对象派生”策略,有一种方法。不幸的是,没有什么boost::nonderivable可以为您美化。


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

class MyClass : final private boost::noncopyable { ... };
于 2010-01-12T21:43:31.447 回答