Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
354 views
in Technique[技术] by (71.8m points)

c++ - 何时使用虚拟析构函数?(When to use virtual destructors?)

I have a solid understanding of most OO theory but the one thing that confuses me a lot is virtual destructors.

(我对大多数面向对象理论有扎实的了解,但令我困惑的一件事是虚拟析构函数。)

I thought that the destructor always gets called no matter what and for every object in the chain.

(我以为无论链中的每个对象是什么,析构函数总是被调用。)

When are you meant to make them virtual and why?

(您打算何时将它们虚拟化?为什么?)

  ask by Lodle translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Virtual destructors are useful when you might potentially delete an instance of a derived class through a pointer to base class:

(当您可能通过指向基类的指针删除派生类的实例时,虚拟析构函数很有用:)

class Base 
{
    // some virtual methods
};

class Derived : public Base
{
    ~Derived()
    {
        // Do some important cleanup
    }
};

Here, you'll notice that I didn't declare Base's destructor to be virtual .

(在这里,您会注意到我没有将Base的析构函数声明为virtual 。)

Now, let's have a look at the following snippet:

(现在,让我们看一下以下代码片段:)

Base *b = new Derived();
// use b
delete b; // Here's the problem!

Since Base's destructor is not virtual and b is a Base* pointing to a Derived object, delete b has undefined behaviour :

(由于Base的析构函数不是virtual并且b是指向Derived对象的Base* ,因此delete b具有未定义的行为 :)

[In delete b ], if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined .

([在delete b ],如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义 。)

In most implementations, the call to the destructor will be resolved like any non-virtual code, meaning that the destructor of the base class will be called but not the one of the derived class, resulting in a resources leak.

(在大多数实现中,对析构函数的调用将像任何非虚拟代码一样进行解析,这意味着将调用基类的析构函数,但不会调用派生类之一,从而导致资源泄漏。)

To sum up, always make base classes' destructors virtual when they're meant to be manipulated polymorphically.

(综上所述,在需要对基类的析构函数进行多态操作时,始终使它们virtual 。)

If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destructor protected and nonvirtual;

(如果要防止通过基类指针删除实例,则可以使基类的析构函数受保护且非虚拟;)

by doing so, the compiler won't let you call delete on a base class pointer.

(这样,编译器将不允许您在基类指针上调用delete 。)

You can learn more about virtuality and virtual base class destructor in this article from Herb Sutter .

(您可以从Herb Sutter的本文中了解有关虚拟性和虚拟基类析构函数的更多信息。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...