2011-07-25 55 views
3

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

回答

6

从C++标准(部分10.3):

如果虚拟成员函数vf在类Base和 类Derived被声明,直接或间接衍生从Base[...] 然后Derived::vf也是虚拟(它是否被这样声明) 。

所以,是的。

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 
} 
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关键字,它克服了这种问题。

1
or I need to explicitly put 'virtual' before '~B() {...}' 

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

相关问题