0

I have this code:

class Parent {
    public: 
    Parent() {
        init();
    }

    virtual void function() {
        std::cout<<"Parent function"<<std::endl;
    }

    private:
    virtual void init() {
        function();
    }
};

class Child : public Parent {
    public:
    virtual void function() {
        std::cout<<"child function"<<std::endl;
    }
};

I want call the function of Child from the init function of Parent when the instance of Child is created. In this case the output is "child function" instead of "Parent function".

gulliver
  • 86
  • 2
  • 9
  • 2
    You should avoid calling virtual functions from constructor [read here for more details](https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors). – rafix07 Jul 25 '19 at 20:59
  • It is not necessary calling the virtual method init. The virtual can be remove. – gulliver Jul 26 '19 at 03:43

2 Answers2

2

That is impossible.

Functions directly called from constructors are called non-virtually, and when those do call virtual functions they are called virtually, but the virtual dispatch will select the function for the parent class. You can't call function of a derived class from parent class constructor.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
1

Method functions called from constructor/destructor are not called virtually.

You might create factory method to allow to call init virtually

class Parent {
protected: 
    Parent() {}

public:
    virtual void function() {
        std::cout<<"Parent function"<<std::endl;
    }

    template <typename T, typename ... Ts>
    T MakeChild(Ts&&... args)
    {
        static_assert(std::is_base_of<Parent, T>::value, "!");
        T child(std::forward<Ts>(args)...);
        child.init();
        return child;
    }

private:
    virtual void init() {
        function();
    }
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Requires child to be movable/copyable, which might not be great. – SergeyA Jul 25 '19 at 21:08
  • @SergeyA: No longer with C++17 :-) but anyway, as we work with polymorphic class, returning `std::unique_ptr` would probably be more appropriated, and so those restrictions disappear too ;-) – Jarod42 Jul 25 '19 at 21:12
  • I do not think copy elision guarantees apply to NRVO, or actually, I am certain they do not: https://en.cppreference.com/w/cpp/language/copy_elision – SergeyA Jul 25 '19 at 21:16
  • Indeed,/me is sad :-/ comment about smart pointer still applies though. – Jarod42 Jul 25 '19 at 21:19
  • The method init can be non-virtually :-). – gulliver Jul 26 '19 at 03:44