首页 文章

C:从同一个类的成员函数调用纯虚函数

提问于
浏览
4

考虑以下2个程序 .

#include <iostream>
using std::cout;
class Base {
    public:
        virtual void f()=0;
        void g() {
            f();
        }
        virtual ~Base() { }
};
class Derived : public Base
{
    public:
    void f() {
        cout<<"Derived::f() is called\n";
    }
     ~Derived() {}
};
class Derived1 : public Base
{
    public:
    void f() {
        cout<<"Derived1::f() is called\n";
    }
    ~Derived1() { }
};
int main() {
    Derived1 d;
    Base& b=d;
    b.g();
    b.f();
}

编译并运行良好并给出预期的结果..

#include <iostream>
using std::cout;
class Base {
    public:
        virtual void f()=0;
        Base() {
            f();    // oops,error can't call from ctor & dtor
        }
};
class Derived : public Base
{
    public:
        void f() {
            std::cout<<"Derived::f() is called\n";
        }
};
int main() { Derived d; Base& b=d; b.f(); }

上述程序编译失败 . 为什么允许从声明纯虚函数的同一个类的成员函数中调用纯虚函数?是这样做还是未定义的行为,因为派生类仍然不提供纯虚函数的实现?为什么不能从同一个类的构造函数和析构函数中调用纯虚函数?我知道Derived类构造函数可以调用基类的纯虚函数 . C标准对此有何看法?

2 回答

  • 5

    “为什么无法从构造函数中调用纯虚函数?”

    因为此时最终类没有完全构造,并且 vtable 未完全设置,所以正确调度函数调用 .


    您也可以使用 static 关系作为基类和派生类,如CRTP所建议:

    template<class DerivedType>
    class Base {
        public:
            void g() {
                static_cast<DerivedType*>(this)->f();
            }
            virtual ~Base() { }
    };
    
    class Derived : public Base<Derived>
    {
        public:
        void f() {
            cout<<"Derived::f() is called\n";
        }
         ~Derived() {}
    };
    
    class Derived1 : public Base<Derived1>
    {
        public:
        void f() {
            cout<<"Derived1::f() is called\n";
        }
        ~Derived1() { }
    };
    
  • 1

    为什么允许从声明纯虚函数的同一类的成员函数调用纯虚函数?

    因为这在技术上是可行的并且在实践中使用:请参阅模板方法模式 .

    为什么不能从同一个类的构造函数和析构函数中调用纯虚函数?

    这在技术上不是直接在C中实现(还没有vtable) . 但更重要的是,你不应该需要它,因为你在调用构造函数时总是知道对象的确切类 .

相关问题