【发布时间】:2018-11-30 15:36:57
【问题描述】:
我有自动生成的类,但我想让最终用户添加自定义成员函数和构造函数。
我的方法是使用没有成员变量只有函数的 CRTP 基类。
问题在于构造函数。如果我在我的 CRTP 中定义了一个构造函数,我将无法正确访问子类,因为它尚未构造,因为子类构造函数仅在构造 CRTP 基础之后才被调用。
#include <iostream>
#include <string>
template<class Child>
struct Foo {
Foo(std::string i) {
// Childs constructor is not run yet.
std::cout << static_cast<Child&>(*this).d.size(); // Prints trash
static_cast<Child&>(*this).d = i; // Segfault here
(void) i;
}
};
// Cannot change this class.
struct Bar : Foo<Bar> {
using base_t = Foo<Bar>;
using base_t::base_t;
std::string d;
};
int main()
{
Bar bar("asdgasdgsag");
std::cout << "bar.d: " << bar.d << std::endl;
}
有没有办法解决这个问题?
【问题讨论】:
-
@FrançoisAndrieux:是的,到目前为止很清楚。
-
这是一个众所周知的问题。虚函数和继承也会有同样的问题。无法解决,构造函数不能使用派生类的东西。
-
您需要两阶段初始化。先构造,然后在单独的初始化函数中完成。
-
问题解决了!第二阶段可以通过使用默认参数临时绑定到构造函数参数来完成!
-
如果您发现自己编写了很多具有“相同”成员的类,请考虑将该成员移至它们的公共基类。在您的情况下,
Foo的所有孩子都应该有std::string d;成员。将其移至Foo是自然而恰当的。
标签: c++ c++11 constructor crtp