启用可覆盖init函数的优雅方式

时间:2012-09-20 01:53:30

标签: c++ c++11

由于曾经无法在基类构造函数中调用派生类覆盖函数,我想模仿这种行为(类似于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 的角度来看)以及实例化Object的唯一方法。 问题是这是否可以更简单地实现,因为现在每个派生类都必须实现create

1 个答案:

答案 0 :(得分:4)

我看不到你的代码会编译。我无法看到虚拟init方法的重点,尽管它确实提出了两阶段构造。这是邪恶的,你可以通过阅读Bjarne Stroustrup的appendix E to “The C++ Programming Language”,尤其是E3.5节来了解更多信息。

FAQ中概述了在基类构造函数中执行派生类初始化的常用方法。由于我曾经说服Marshall添加这个FAQ项目,我也可以自由地引导你到我自己的blog

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

<小时/> 哦,我忘了。关于构造期间动态类型的C ++规则的要点是提供类型安全构造。在Java和C#中,您可以轻松地引入一个错误,您可以访问某些派生类的未初始化成员,但不能使用C ++。

安全性类型的两阶段构造沟渠,并且难以编写异常安全使用代码,以换取为1990年代早期的编译器干净地编码它的能力(但实际上,谁需要这种能力)。

其他常用解决方案旨在确保类型安全。