c++ - 我可以调用虚函数来初始化基类子对象吗?

标签 c++ constructor virtual ctor-initializer

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

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

最佳答案

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

在初始化所有基数之前,构造函数初始化程序中这是一个不同的游戏:

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.

关于c++ - 我可以调用虚函数来初始化基类子对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25754796/

相关文章:

c++ - sprintf 小数点太多/太少

android - 如何在 Android(NDK) 中使用 CPR 库?

c++ - 实现多个函数调用是不好的做法吗?

java - 什么是初始化 block ?

c++ - 使用 Auto 时在派生类中使用虚拟析构函数强制复制构造函数

C++ fstream 告诉行为

java - Java中重载构造函数时

c++ - 在 C++ 中正确使用构造函数

c++ - 虚拟基类初始化难题

c++ - 对派生对象的 C++ 虚函数调用是否通过 vtable?