Search code examples
c++oopderived-class

c++ derived class needs to tweak base class via callback


I would like to create a base class ==> derived class setup where the base class' constructor has a callback to run a (possibly complex) function to modify the base class' private member with information from the derived class. However, I'm running into a chicken and an egg problem because the base class constructor runs before the derived class' members are initialized. Here's the code to demonstrate the problem:

#include <iostream>
#include <functional>

class B
{
  public:
    typedef std::function<void(std::string &)> mod_func_t;

    B(const mod_func_t &m) : foo("base str")
    {   
      std::cout << "Base constructor\n";
      m(foo);
      std::cout << "base constructor finally has: " << foo << std::endl;
    }   

  private:
    std::string foo;
};

class D : public B
{
  public:
    D(const std::string &input) :
      B(std::bind(&D::my_f, this, std::placeholders::_1)),
      input_(input)
    {   
      std::cout << "Derived constructor\n";
    }   

  private:
    void my_f(std::string &s) 
    {   
      std::cout << "Derived class' modification function\n";
      s += input_; // <== Crashes here because input_ is not yet constructed
    }   

    const std::string input_;
};

int main()
{
  D d("my input");
  return 0;
}

What is the correct way to do this?


Solution

  • One approach is to let D calculate the adjusted string before calling the constructor of B.

    class D : public B {
      D(std::string str)
       : B(my_f(str))
      {}
    
      std::string my_f(std::string str) { return str + "..."; }
    };
    

    A second approach is to let the body of constructor D do some work. Here adjust_base could also be virtual.

    class D : public B {
      D(std::string str)
       : B(str)
      {
         adjust_base();
      }
    
      void adjust_base();
    };