简体   繁体   中英

Access inherited method during construction of base class?

I have a weird C++ problem where I'm not sure if it works correctly this way or If I missed something.

There is a class A which inherits from ABase . ABase and A both have a method Generate() while A::Generate() should overwrite ABase::Generate() .

Generate() is called out of the constructor of ABase.

Now my problem:

I do a new A() which first jumps into constructor of A and from there into constructor of ABase. ABase::ABase() now calls Generate() . What I want to do: A::Generate() should be executed (since this overwrites ABase::Generate() ).

Unfortunately it seems out of the constructor of ABase only ABase::Generate() is called and never A::Generate() .

I gues that happens because A is not fully constructed at this stage? Or is there a way to let ABase::ABase() make use of A::Generate() ?

You do not want A::Generate() to be executed, since this would involve executing a function on a class which has not been constructed. C++ has been designed intentionally so that during construction, the dynamic type of the object is the type being constructed, precisely to avoid this sort of problem.

It's not easy to work around, and definitely not pretty, but you may be able to do something like this:

class ABase
{
public:
    ABase()
    {
        // Normal constructor, calls `Generate`
    }

    virtual void Generate() { ... }

    // ...

protected:
    struct do_not_call_generate_tag {};

    const static do_not_call_generate_tag do_not_call_generate;

    ABase(const do_not_call_generate_tag)
    {
        // Same as the normal `ABase` constructor, but does _not_ call `Generate`
    }
};

class A : public ABase
{
public:
    A()
        : ABase(ABase::do_not_call_generate)
    {
        // Other initialization
        PrivateGenerate();
    }

    void Generate()
    {
        PrivateGenerate();
    }

private:
    void PrivateGenerate()
    {
        // Do what your old `Generate` does
    }
};

In order to have nicely constructed and initialized objects, I would separate these two tasks from each other:

class ABase
{
public:
    virtual void Generate()
    {
        //...
    }
};

class A: public ABase
{
public:
    virtual void Generate()
    {
        //...
    }
};

Now you have to perform both tasks explicitly

A *someA = new A();
someA->Generate();

...but you can group this inside eg a Create() method or redefine the new operator or the like.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM