假设我们有以下两个类,A是具有虚拟析构函数的基类,B是派生类,其析构函数没有'virtual'限定符。我的问题是,如果我要从B派生更多的类,B的析构函数会自动继承虚拟,或者我需要在'~B(){...之前明确地放置'virtual' }“的
class A
{
public:
A() { std::cout << "create A" << std::endl;};
virtual ~A() { std::cout << "destroy A" << std::endl;};
};
class B: A
{
public:
B() { std::cout << "create B" << std::endl;};
~B() { std::cout << "destroy B" << std::endl;};
};
答案 0 :(得分:6)
从C ++标准(第10.3节):
如果在类
vf
中声明虚拟成员函数Base
并且在 从[{1}}, [...] 直接或间接派生的班级Derived
然后Base
也是虚拟的(无论是否如此声明)。
是的。
答案 1 :(得分:6)
如果基类方法是virtual
,则所有后续派生类方法将变为virtual
。但是,IMO将virtual
放在方法之前是一种很好的编程习惯;只是为了向读者表明功能的本质。
另请注意,在某些极端情况下,您可能会收到意外结果:
struct A {
virtual void foo(int i, float f) {}
};
sturct B : A {
void foo(int i, int f) {}
};
实际上,B::foo()
并未用A::foo()
机制覆盖virtual
;相反,它隐藏了它。因此无论你使B::foo()
虚拟,都没有优势。
在C ++ 0x中,您有override
个关键字,可以解决此类问题。
答案 2 :(得分:1)
虚拟性一直在继承。您只需要在顶层基类中指定它。
对于析构函数和普通成员函数都是如此。
示例:
class Base { virtual void foo() { std::cout << "Base\n"; } };
class Derived1 : public Base { void foo() { std::cout << "Derived1\n"; } };
class Dervied2 : public Derived1 { void foo() { std::cout << "Derived2\n"; } };
int main()
{
Base* b = new Base;
Base* d1 = new Derived1;
Base* d2 = new Derived2;
Derived1* d3 = new Derived2;
b->foo(); // Base
d1->foo(); // Derived1
d2->foo(); // Derived2
d3->foo(); // Derived2
}
答案 3 :(得分:1)
or I need to explicitly put 'virtual' before '~B() {...}'
不,你不需要,虽然你可以把虚拟放在这里为读者提供更清晰的代码。这不仅适用于析构函数,也适用于所有成员函数。