我知道不应该在构造函数中直接或间接调用虚函数,但这段代码运行正常 我在这里安全吗?
#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
};
答案 0 :(得分:5)
通常可以在构造函数和/或析构函数中调用虚拟成员。
在所有基础初始化之前,它在ctor初始值设定项中是一个不同的游戏:
12.6.2初始化基数和成员
[class.base.init]
[...]
可以为正在构建的对象调用成员函数(包括虚拟成员函数,10.3)。 类似地,正在构造的对象可以是typeid
运算符(5.2.8)或dynamic_cast
(5.2.7)的操作数。但是,如果在基类的所有mem-initializer完成之前,在 ctor-initializer (或直接或间接从ctor-initializer调用的函数)中执行这些操作,操作结果未定义。