假设我有两个类:
class Base{};
class Derived: public Base{};
在这种情况下,如果我声明了关于变量的内容,那么就没有d'tor(析构函数)。
Base b;
Derived d;
我的编译器将为我生成析构函数,我的问题是,b
和d
的默认析构函数是否是虚拟的?
假设我有两个类:
class Base{};
class Derived: public Base{};
在这种情况下,如果我声明了关于变量的内容,那么就没有d'tor(析构函数)。
Base b;
Derived d;
我的编译器将为我生成析构函数,我的问题是,b
和d
的默认析构函数是否是虚拟的?
class Base {
public:
virtual ~Base() {}
};
Base
和Derived
的析构函数将不会是virtual
。要创建一个virtual
析构函数,您需要显式标记它:
struct Base
{
virtual ~Base() {}
};
实际上现在只有一个原因使用虚析构函数。那就是为了消除gcc警告:“类'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
!祝好运!shared_ptr
或等效物。那些不试图管理如何被使用的类更加灵活。给这样的类一个虚析构函数可以在几乎没有额外成本的情况下使它在更多的情况下被正确使用。在这种情况下,用户通常不会收到任何关于不正确使用的警告。类应该尽可能地易于正确使用。 - CB BaileyBase* pBase = new Concrete; shared_ptr<Base> shpBase(pBase);
是危险的,但这也是Daniel想表达的一部分。他只是想说 shared_ptr<Base> shpBase(new Concrete);
不危险,因为有 shared_ptr
的构造函数模板。 - CB Bailey它们不会是虚拟的。然而,如果你在基类中声明(和定义)了一个虚拟析构函数,那么派生类的析构函数将自动成为虚拟函数。希望这有帮助。
只是为Daniel Lidström的回答增加一个例子
只要您始终将分配的对象存储在shared_ptr中,那么您就不需要虚析构函数。
如果使用shared_ptr如下:
std::shared_ptr<Base> b(new Concrete);
Base* pBase = new Concrete;
std::shared_ptr<Base> b(pBase);
#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;
}
}
除非你明确地将它们标记为虚拟的,否则它们怎么可能是虚拟的呢?