2

由于曾经无法在基类构造函数中调用派生类的覆盖函数,因此我想模拟这种行为(类似于 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>();
    }


};

Wherecreate可以替代构造函数(从公共的角度来看),并且是实例化对象的唯一方法。问题是这是否可以更简单地实现,因为现在每个派生类都必须实现create.

4

1 回答 1

4

我看不到您的代码会编译。而且我看不到虚拟init方法的意义,尽管它确实建议了两阶段构建。这只是邪恶的,您可以通过阅读 Bjarne Stroustrup 的“C++ 编程语言”附录 E,尤其是 E3.5 部分了解更多信息。

FAQ中概述了在基类构造函数中进行派生类初始化的常用方法。由于我曾经说服 Marshall 添加该常见问题解答项目,因此我也可以随意将您引导到我自己的博客

以后请记住,首先查看常见问题解答通常是个好主意。


哦,我忘了。关于构造期间动态类型的 C++ 规则的要点是提供类型安全的构造。在 Java 和 C# 中,您可以很容易地引入一个错误,即您正在访问派生类的一些未初始化的成员,但在 C++ 中则不然。

两阶段构造抛弃了类型安全,并使得编写异常安全使用代码变得困难,以换取为 1990 年代早期的编译器编写干净代码的能力(但实际上,谁需要这种能力)。

其他常见的解决方案旨在保持类型安全。

于 2012-09-20T02:35:59.130 回答