派生类的成员函数是否从基类继承虚拟性?

Does derived class' member functions inherit virtualness from base class?

本文关键字:基类 继承 虚拟性 是否 成员 函数 派生      更新时间:2023-10-16

假设我们有以下两个类,A 是具有虚拟析构函数的基类,B 是其析构函数没有"虚拟">限定符的派生类。我的问题是,如果我从 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;};
};

从C++标准(第 10.3 节(:

如果在类中声明了虚拟成员函数vf Base 和 一个类Derived,直接或间接派生自Base[...] 那么Derived::vf也是虚拟的(无论它是否如此声明(。

所以是的。

如果基类方法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关键字,它克服了这些问题。

虚拟性是一路继承下来的。您只需要在顶级基类中指定它。

对于析构函数和普通成员函数都是如此。

例:

class Base { virtual void foo() { std::cout << "Basen"; } };
class Derived1 : public Base { void foo() { std::cout << "Derived1n"; } };
class Dervied2 : public Derived1 { void foo() { std::cout << "Derived2n"; } };
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
}
or I need to explicitly put 'virtual' before '~B() {...}'

不,你不需要,尽管你可以把虚拟放在这里,使代码对读者来说更清晰。这不仅适用于析构函数,也适用于所有成员函数。