2

我知道不应该在构造函数中直接或间接调用虚函数,但是这段代码运行良好。
我这里的东西安全吗?

#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"
}

如果不是,以下(基于评论)是否是正确的解决方法?

// 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
};
4

1 回答 1

5

在构造函数和/或析构函数中调用虚拟成员通常是可以的。

但是,在初始化所有基础之前,在 ctor 初始化程序中这是一个不同的游戏:

12.6.2 初始化基和成员[class.base.init]

[...]
14 个成员函数(包括虚拟成员函数,10.3)可以为正在构建的对象调用。类似地,正在构造的对象可以是运算typeid符 (5.2.8) 或dynamic_cast(5.2.7) 的操作数。但是,如果这些操作在基类的所有 mem-initializer 完成之前在ctor-initializer(或直接或间接从 ctor-initializer 调用的函数中)执行,则操作的结果是未定义的。

于 2014-09-09T23:33:10.857 回答