默认虚拟机

时间:2010-10-10 09:05:08

标签: c++ destructor

我们假设我有两个班级:

class Base{};

class Derived: public Base{};

没有人,如果我宣布变量:

Base b;
Derived d;

我的编译器将为我生成,我的问题是,b and d的默认值是虚拟的还是不是?

6 个答案:

答案 0 :(得分:10)

  

我的问题是,b和d的d将是虚拟的

不,他们不会。如果你想要一个虚拟析构函数,你必须定义自己的析构函数,即使它的实现与编译器提供的实现完全相同:

class Base {
  public:
    virtual ~Base() {}
};

答案 1 :(得分:7)

BaseDerived的析构函数不会是virtual。要创建virtual析构函数,您需要明确标记它:

struct Base
{
    virtual ~Base() {}
};

实际上现在只有一个原因是使用虚拟析构函数。那就是关闭gcc警告:“class'Base'具有虚函数但非虚析构函数”。只要您始终将分配的对象存储在shared_ptr中,那么您实际上不需要虚拟析构函数。方法如下:

#include <iostream>   // cout, endl
#include <memory>     // shared_ptr
#include <string>     // string

struct Base
{
   virtual std::string GetName() const = 0;
};

class Concrete : public Base
{
   std::string GetName() const
   {
      return "Concrete";
   }
};

int main()
{
   std::shared_ptr<Base> b(new Concrete);
   std::cout << b->GetName() << std::endl;
}

shared_ptr将正确清理,无需虚拟析构函数。请记住, 需要使用shared_ptr

祝你好运!

答案 2 :(得分:5)

  

我的问题是,b和d的d将是虚拟的

简短回答:不是!

答案 3 :(得分:3)

它们不会是虚拟的。但是,如果您在Base中声明(并定义)了一个虚拟dtor,那么派生的dtor将自动为虚拟。 HTH。

答案 4 :(得分:2)

除非您明确将它们设为虚拟

,否则它们如何才能成为虚拟

答案 5 :(得分:1)

只需向Daniel Lidström's answer

添加一个示例

As long as you always store your allocated objects in a shared_ptr, then you really don't need a virtual destructor.

如果使用这样的shared_ptr:

    std::shared_ptr<Base> b(new Concrete);

然后在销毁对象时调用Concrete析构函数和Base析构函数。

如果使用这样的shared_ptr:

Base* pBase = new Concrete;
std::shared_ptr<Base> b(pBase);

然后在销毁对象时仅调用Base析构函数。

这是an example

#include <iostream>   // cout, endl
#include <memory>     // shared_ptr
#include <string>     // string

struct Base
{
   virtual std::string GetName() const = 0;
   ~Base() { std::cout << "~Base\n"; } 
};

struct Concrete : public Base
{
   std::string GetName() const
   {
      return "Concrete";
   }
   ~Concrete() { std::cout << "~Concrete\n"; } 
};

int main()
{
  {
    std::cout << "test 1\n";
    std::shared_ptr<Base> b(new Concrete);
    std::cout << b->GetName() << std::endl;
  }

  {
    std::cout << "test 2\n";
    Base* pBase = new Concrete;
    std::shared_ptr<Base> b(pBase);
    std::cout << b->GetName() << std::endl;
  }

}