Invoking virtual function and pure-virtual function from a constructor

泪湿孤枕 提交于 2019-11-30 15:19:57
Alok Save

Do not call pure virtual functions from constructor as it results in Undefined Behavior.

C++03 10.4/6 states

"Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined."

You get an compilation error because you have not defined the pure virtual function virtualfunc() in the Base class. To be able to call it, it must have an body.

Anyways, calling pure virtual functions in constructors should be avoided as it is Undefined Behavior to do so.

e.s. kohen

In C++ 11, there is a work around.

In the process of Constructor Delegation, you can, in fact, call an implementation of a pure virtual method--as long as at least one of the constructors of the class implementing that pure virtual method has been completed before the pure virtual call is invoked.

You could/should use the "final" keyword in order to ensure that the behavior for subclasses is not unpredictable.

See: C++ 11 Delegated Constructor Pure Virtual Method & Function Calls — Dangers?

#include <string>

/**************************************/
class Base
{
public:
    int sum;
    virtual int Do() = 0;

    void Initialize()
    {
        Do();
    }
    Base()
    {
    }
};

/**************************************/
// Optionally declare class as "final" to avoid
// issues with further sub-derivations.
class Derived final : public Base
{
public:

    virtual int Do() override final
    {
        sum = 0 ? 1 : sum;
        return sum / 2 ; // .5 if not already set.
    }

    Derived(const std::string & test)
        : Derived() // Ensure "this" object is constructed.
    {
        Initialize(); // Call Pure Virtual Method.
    }
    Derived()
        : Base()
    {
        // Effectively Instantiating the Base Class.
        // Then Instantiating This.
        // The the target constructor completes.
    }
};




/********************************************************************/
int main(int args, char* argv[])
{
    Derived d;
    return 0;
}

You should remember that when you are in a Base Class constructor there is no a derived class. More information:

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5

When you are trying to invoke pure virtual function there is no implementation of it yet.

There is a lot of solutions. The easiest one is to create a another member function "init()" which you will invoke after the constructor of a base class.

The compiler is not required to assume that a pointer has been set for a pure virtual function before the constructor has completed. In other words, it's not required to know that you have a definition for the function at that point. Therefore the behavior is undefined. On some compilers (MSVC) it will work as you expect, and on others it will give you the error that you are currently getting. On some others it will compile, but you will get a segmentation fault.

It's really a bad idea to call ANY virtual function from a constructor anyway, because it makes the intent of your code unclear and confusing.

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