我可以调用一个虚拟函数来初始化基类子对象吗

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

本文关键字:初始化 基类 对象 函数 虚拟 调用 一个 我可以      更新时间:2023-10-16

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

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

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

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

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

不过,在所有碱基初始化之前,ctor初始化器中的游戏是不同的:

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

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