C++: call pure virtual function from member function of same class

痞子三分冷 提交于 2019-12-07 06:11:10

问题


Consider the following 2 programs.

#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();
}

Compiles & runs fine and gives expected outcome..

#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(); }

The above program fails in compilation. Why is it allowed to call a pure virtual function from the member function of the same class in which the pure virtual function is declared? Is it fine to do this or is it undefined behavior because derived class still doesn't provide an implementation of the pure virtual function? Why can't a pure virtual function be called from constructor & destructor of the same class? I know that Derived class constructors can call pure virtual functions of the base class. What does the C++ standard say about this?


回答1:


"Why pure virtual function can't be called from constructor ... ?"

Because the final class isn't constructed completely at this point, and the vtable isn't completely setup, to dispatch the function call correctly.


You may alternatively use a static relationship for base and derived class like proposed with the 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() { }
};



回答2:


Why it is allowed to call pure virtual function from the member function of same class in which pure virtual function is declared?

Because this is technically feasible and used in practice: see the Template Method pattern.

Why pure virtual function can't be called from constructor & destructor of the same class?

This is technically not straight-forward to implement in C++ (no vtable yet). But more fundamentally, you should not need it anyway since you always know the exact class of your object when calling a constructor.



来源:https://stackoverflow.com/questions/30415669/c-call-pure-virtual-function-from-member-function-of-same-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!