c++ derived class 需要通过回调调整 base class
c++ derived class needs to tweak base class via callback
我想创建一个基础 class ==> 派生的 class 设置,其中基础 class' 构造函数具有对 运行 的回调(可能很复杂) 函数使用派生 class 中的信息修改基 class' 私有成员。但是,我 运行 陷入先有鸡还是先有蛋的问题,因为基础 class 构造函数 运行 在 派生的 class 之前 ]' 成员被初始化。下面是演示问题的代码:
#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;
}
正确的做法是什么?
我相信 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;
}
一种方法是在调用B
的构造函数之前让D计算调整后的string
。
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();
};
我想创建一个基础 class ==> 派生的 class 设置,其中基础 class' 构造函数具有对 运行 的回调(可能很复杂) 函数使用派生 class 中的信息修改基 class' 私有成员。但是,我 运行 陷入先有鸡还是先有蛋的问题,因为基础 class 构造函数 运行 在 派生的 class 之前 ]' 成员被初始化。下面是演示问题的代码:
#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;
}
正确的做法是什么?
我相信 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;
}
一种方法是在调用B
的构造函数之前让D计算调整后的string
。
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();
};