默认虚拟机

roo*_*kie 9 c++ destructor

我们假设我有两个类:

class Base{};

class Derived: public Base{};
Run Code Online (Sandbox Code Playgroud)

没有d tor,在这种情况下如果我声明变量:

Base b;
Derived d;
Run Code Online (Sandbox Code Playgroud)

我的编译器会为我生成,我的问题是,默认的b and d是否是虚拟的?

sbi*_*sbi 10

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

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

class Base {
  public:
    virtual ~Base() {}
};
Run Code Online (Sandbox Code Playgroud)


Dan*_*röm 7

破坏者BaseDerived将来的破坏者virtual.要构建virtual析构函数,您需要明确标记它:

struct Base
{
    virtual ~Base() {}
};
Run Code Online (Sandbox Code Playgroud)

实际上现在只有一个原因是使用虚拟析构函数.那就是关闭gcc警告:"class'Base'具有虚函数但非虚析构函数".只要您始终将分配的对象存储在a中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;
}
Run Code Online (Sandbox Code Playgroud)

shared_ptr会正确地清理,而不需要一个虚析构函数.记住,你需要使用shared_ptr,但!

祝好运!

  • 我认为暗示多态基类应该只有虚拟析构函数才能使警告静音是不好的建议.不为设计为继承层次结构的公共基类的类提供虚拟析构函数会强制用户使用`shared_ptr`或等效项.不试图管理它们如何使用的类更通用.为这样的类提供虚拟析构函数允许它在更多情况下以更少的额外成本正确使用.在这种情况下,用户通常不会收到有关错误使用的警告.类应该易于正确使用. (6认同)
  • @Armen:shared_ptr知道静态类型是Concrete.它知道这个,因为我在它的构造函数中传递它!看起来有点像魔术,但我可以向你保证这是设计和非常好. (2认同)
  • @Oli:当你递归地应用RAII时,总是使用shared_ptr,效果是突然你根本不需要一个析构函数!shared_ptr可以包装任何资源,当您可以使用新的lambda语法指定自定义删除器时更方便. (2认同)
  • @Charles:你是对的.由于我无法监督OP的工作,我无法知道他是否遵守了要求.所以我的建议并不适合初学者.如果他和我一起工作,我会引导他走上设计模式的道路.任何接口层次结构都需要使用抽象工厂.但是,这是我不想在这里进行的讨论. (2认同)
  • @ Tomaka17:你说'Base*pBase = new Concrete是正确的; shared_ptr <Base> shpBase(pBase);`很危险但这是Daniel的观点的一部分.他所说的只是`shared_ptr <Base> shpBase(new Concrete);`并不危险,因为`shared_ptr`的构造函数模板,它不是危险的. (2认同)

Pra*_*rav 5

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

简短回答:不是!