微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c++派生类需要通过回调来调整基类

如何解决c++派生类需要通过回调来调整基类

我想创建一个基类 ==> 派生类设置,其中基类的构造函数一个回调来运行(可能是复杂的)函数,以使用派生类的信息修改基类的私有成员。但是,我遇到了鸡和蛋的问题,因为基类构造函数在派生类的成员初始化之前运行。下面是演示问题的代码

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

这样做的正确方法是什么?

解决方法

一种方法是让 D 在调用 string 的构造函数之前计算调整后的 B

class D : public B {
  D(std::string str)
   : B(my_f(str))
  {}

  std::string my_f(std::string str) { return str + "..."; }
};

第二种方法是让构造函数 D 的主体做一些工作。这里的 adjust_base 也可以是 virtual

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

  void adjust_base();
};
,

我相信 CRTP 可以帮助您解决这个问题。 有一个简单的例子:

#include <iostream>
#include <functional>

template <typename Derived>
class B
{
  public:
 
    B() : foo("base str")
    {   
      static_cast<Derived*>(this)->m(foo);
      std::cout << "Base constructor\n";
      std::cout << "base constructor finally has: " << foo << std::endl;
    }
    
    void m(std::string& str) { //... }   

  private:
    std::string foo;
    friend Derived;
};

class D : public B<D>
{
  public:
    D(std::string &input) :
      B(),input_(input)
    {   
      std::cout << "Derived constructor\n";
    }   
    void m(const std::string& str) { //... }

  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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。