【问题标题】: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 放在此处以使代码对读者更清晰。这不仅适用于析构函数,也适用于所有成员函数。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-12-19
            • 1970-01-01
            • 1970-01-01
            • 2017-04-14
            • 1970-01-01
            • 2016-03-04
            • 1970-01-01
            相关资源
            最近更新 更多