简体   繁体   English

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

[英]C++ initialize object in constructor (polymorphic)

I am currently trying to achieve something in C++ I do in Java all the time: Let's say that I have a function bool init() as a member of my class A that gets called in the constructor of A and if it returns false , the constructor will throw an exception. I am currently trying to achieve something in C++ I do in Java all the time: Let's say that I have a function bool init() as a member of my class A that gets called in the constructor of A and if it returns false , the构造函数会抛出异常。

Now I create a new class B that derives from A but it needs to perform a different initialization so it will return true in different cases than the original A::init() .现在我创建了一个新的 class B派生自A但它需要执行不同的初始化,因此它将在与原始A::init()不同的情况下返回true

In Java I'd simply go ahead and overwrite the method in B and when the constructor of A is involed in the process of constructing B , it will call B::init() from A's constructor and the thing works like a champ.在 Java 中,我只需提前 go 并覆盖B中的方法,当A的构造函数参与到构造B的过程中时,它将从 A 的构造函数调用B::init()并且事情就像一个冠军。

In C++ however I just learned that I can't call virtual functions in a constructor (that is I can but it doesn't behave the same way).在 C++ 但是我刚刚了解到我不能在构造函数中调用虚函数(也就是说我可以但它的行为方式不同)。 My question now is, how I can handle such initializations/checks that are invoked from the constructor but that might need to be changed in a derivative of a class.我现在的问题是,我如何处理从构造函数调用但可能需要在 class 的派生类中更改的此类初始化/检查。
One way would of course be to not call that in the constructor but leave it to the programmer to explicitly call the init() function after creating the object but I don't like that as this could be forgotten leading to strange object state. One way would of course be to not call that in the constructor but leave it to the programmer to explicitly call the init() function after creating the object but I don't like that as this could be forgotten leading to strange object state.


Small example:小例子:
Consider that A and B read a hardcoded file's content.考虑AB读取硬编码文件的内容。 A reads fileA.txt and B reads fileB.txt . A读取fileA.txtB读取fileB.txt I want the construction of the object to only succeed if the respective file is present.我希望 object 的构建只有在相应文件存在时才能成功。 Thus the check has to happen in the constructor of the object.因此检查必须在 object 的构造函数中进行。 If writing the check into the constructor directly will cause B to always fail (assuming that both files can't exist at the same time) so I always went for defining a function that performs the check and that can be overwritten.如果直接将检查写入构造函数会导致B总是失败(假设两个文件不能同时存在)所以我总是去定义一个 function 来执行检查并且可以被覆盖。 What's the C++ way of do this? C++ 的方法是什么?

Whereas having derived class call its own init function seems more appropriate, as alternative, you can create factory function which call your virtual init method:虽然派生 class 调用它自己的 init function 似乎更合适,但您可以创建工厂 function 来调用您的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;
};

For your example you should write an abstract base class from which A & B inherit with a pure virtual static const function which directs which file is read.对于您的示例,您应该编写一个抽象基础 class ,其中 A 和 B 使用纯虚拟 static const function 继承,它指示读取哪个文件。 Abstract classes in C++ are more powerful than interfaces in Java and can consequently be more useful to resolve these kinds of issues than would a java interface. C++ 中的抽象类比 Java 中的接口更强大,因此比 java 接口更有助于解决这类问题。

To actually solve this problem is a more in depth issue which has thus far had me staring at the C++ spec for an hour now trying to figure out.要真正解决这个问题是一个更深入的问题,到目前为止,我一直盯着 C++ 规范一个小时试图弄清楚。 I'll give an update when I figure out exactly what the spec is saying and how if possible to do this.当我确切地弄清楚规范在说什么以及如何做到这一点时,我会给出更新。 This one has really got me.这个真的让我着迷。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM