【问题标题】:Does derived class' member functions inherit virtualness from base class?派生类的成员函数是否从基类继承虚拟性?
【发布时间】:2011-07-25 08:49:49
【问题描述】:
假设我们有以下两个类,A 是具有虚拟析构函数的基类,B 是其析构函数没有 'virtual' 限定符的派生类。我的问题是,如果我要从 B 派生更多类,B 的析构函数会自动继承虚拟性还是我需要在 '~B() {... }'
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;};
};
【问题讨论】:
标签:
c++
inheritance
virtual-functions
【解决方案1】:
来自 C++ 标准(第 10.3 节):
如果在类 Base 中声明了一个虚成员函数 vf 并在
一个类Derived,直接或间接派生自Base,[...]
那么Derived::vf 也是虚拟的(无论是否如此声明)。
是的。
【解决方案2】:
如果基类方法是virtual,那么所有后续派生类方法都会变成virtual。但是,IMO 将 virtual 放在方法之前是一种很好的编程习惯;只是为了向读者说明函数的性质。
另请注意,在某些极端情况下,您可能会得到意想不到的结果:
struct A {
virtual void foo(int i, float f) {}
};
sturct B : A {
void foo(int i, int f) {}
};
实际上,B::foo() 并没有用virtual 机制覆盖A::foo();而是隐藏它。所以不管你把B::foo()设为虚拟,都没有优势。
在 C++0x 中,你有 override 关键字,它克服了这些问题。
【解决方案3】:
虚拟性一直被继承下来。只需要在顶层基类中指定即可。
对于析构函数和普通成员函数都是如此。
例子:
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
}
【解决方案4】:
or I need to explicitly put 'virtual' before '~B() {...}'
不,您不需要,尽管您可以将 virtual 放在此处以使代码对读者更清晰。这不仅适用于析构函数,也适用于所有成员函数。