May I call a virtual function to initialize a base-class sub-object?

血红的双手。 提交于 2019-12-17 21:09:14

问题


I know that virtual functions should not be called either directly or indirectly in a constructor, but this code runs fine.
Is what I have here safe?

#include <iostream>
#include <string>

struct A {
    A (const std::string& name) {std::cout << name << std::endl;}
    virtual std::string tag() const = 0;
};

struct B: A {
    B() : A (tag()) {}
    virtual std::string tag() const override {return "B";}
};

int main() {
    B b; // Output gives "B\n"
}

If not, would the following (based on a comment) be a correct workaround?

// Replacement for class B:

struct B: A {
    B() : A (name()) {}
    virtual std::string tag() const override {return name();}
private:
    static std::string name() {return "B";}  // use static function
};

回答1:


Invoking virtual members in the constructor and/or destructor is generally ok.

It's a different game in the ctor initializer though, before all bases are initialized:

12.6.2 Initializing bases and members [class.base.init]

[...]
14 Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined.



来源:https://stackoverflow.com/questions/25754796/may-i-call-a-virtual-function-to-initialize-a-base-class-sub-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!