由于一旦无法在基类构造函数中调用派生类的覆盖函数,我想模拟这种行为(类似于C#、Java...在幕后正在做什么)。
我能想到的最优雅的(从签名的角度来看)如下:
class Base {
protected:
virtual void init() {
}
template <typename T, typename ...U>
T internal_create(U&& u) {
T instance(std::forward<U>(u)...);
instance.init();
return instance;
}
};
class Derived : public Base {
protected:
Derived() = default;
virtual void init() override {
}
public:
static Derived create() {
return internal_create<Derived>();
}
};
其中 create
可以替代构造函数(从 public 的角度来看),并且是实例化对象的唯一方法。
问题是这是否可以更简单地实现,因为现在每个派生类都必须实现 create
。
最佳答案
我看不到你的代码可以编译。我看不出虚拟 init
方法的意义,尽管它确实建议两阶段构建。这就是邪恶,您可以通过阅读 Bjarne Stroustrup 的 appendix E to “The C++ Programming Language” 来了解更多信息。 ,尤其是 E3.5 节。
FAQ 中概述了在基类构造函数中进行派生类初始化的常用方法。 。由于我曾经说服 Marshall 添加该常见问题解答项目,因此我也可以随时将您引导至我自己的 blog .
以后,请记住,首先查看常见问题解答通常是一个好主意。
哦,我忘了。关于构造期间动态类型的 C++ 规则的要点是提供类型安全构造。在 Java 和 C# 中,您可以很容易地在访问派生类的某些未初始化成员时引入错误,但在 C++ 中则不然。
两阶段构造抛弃了类型安全,并使编写异常安全使用代码变得困难,以换取 1990 年代早期编译器干净编码的能力(但实际上,谁需要这种能力)。
其他常见的解决方案旨在保持类型安全。
关于c++ - 启用可重写 init 函数的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12505161/