C++ 在构造函数中初始化对象(多态)

标签 c++ constructor overriding

我目前正在尝试用 C++ 实现一些我一直用 Java 做的事情:假设我有一个函数 bool init()作为我类的一员AA 的构造函数中被调用如果它返回 false ,构造函数将抛出异常。

现在我创建一个新类 B源自 A但它需要执行不同的初始化,所以它会返回 true在与原始情况不同的情况下 A::init() .

在 Java 中,我会简单地继续并覆盖 B 中的方法。当 A 的构造函数时参与构建过程B , 它会调用 B::init()来自 A 的构造函数,它运行得非常出色。

但是在 C++ 中,我刚刚了解到我不能在构造函数中调用虚函数(我可以,但它的行为方式不同)。我现在的问题是,我如何处理从构造函数调用但可能需要在类的派生类中更改的此类初始化/检查。
一种方法当然是不在构造函数中调用它,而是让程序员显式调用 init()。创建对象后运行,但我不喜欢这样,因为这可能会被遗忘,导致奇怪的对象状态。


小例子:
考虑一下 AB读取硬编码文件的内容。 A阅读 fileA.txtB阅读 fileB.txt .我希望对象的构造只有在相应的文件存在时才会成功。因此,检查必须在对象的构造函数中进行。如果直接将检查写入构造函数将导致 B总是失败(假设两个文件不能同时存在)所以我总是去定义一个函数来执行检查并且可以被覆盖。执行此操作的 C++ 方法是什么?

最佳答案

虽然让派生类调用它自己的 init 函数似乎更合适, 作为替代方案,您可以创建调用 virtual init 方法的工厂函数:

class A
{
public:
    virtual ~A() = default;
    virtual bool init() = 0;

public:
    template <typename T, typename ... Ts>
    static T Create(Ts&&...args)
    {
        static_assert(std::is_base_of<A, T>::value);
        T derived(std::forward<Ts>(args)...);
        if (!derived.init()) {
            throw std::runtime_error("...");
        }
        return derived;
    }
protected:
    A() = default;
};

class B : public A
{
    friend class A; // For factory
protected:
    B(/*..*/);
public:
    bool init() override;
};

关于C++ 在构造函数中初始化对象(多态),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58034851/

相关文章:

c++ - 使用 Visual C++ 和 MFC 发出 ping 声音错误

c++ - 有没有办法比较用 int 初始化的 char 类型数组的 2 个元素?

c++ - 在 C++ 的菱形问题中,为什么我们需要从子类调用 grand_parent 构造函数?

java - 创建类时是否调用 Java 构造函数?没有创建对象时出现 "constructor cannot be applied to given types"错误

java - Java 中继承和重写方法的输出令人困惑

c++ - 无法应用数组 unique_ptr 的 to_address

c++ - 如何将返回类型推导、模板实例化与头文件结合起来?

java - 在子类的构造函数中抛出异常

objective-c - Objective-C - 反射和覆盖方法?

javascript - 如何重写 XMLHttpRequest?