我们假设我有两个班级:
class Base{};
class Derived: public Base{};
没有人,如果我宣布变量:
Base b;
Derived d;
我的编译器将为我生成,我的问题是,b and d
的默认值是虚拟的还是不是?
答案 0 :(得分:10)
不,他们不会。如果你想要一个虚拟析构函数,你必须定义自己的析构函数,即使它的实现与编译器提供的实现完全相同:我的问题是,b和d的d将是虚拟的
class Base {
public:
virtual ~Base() {}
};
答案 1 :(得分:7)
Base
和Derived
的析构函数不会是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)
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析构函数。
#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;
}
}