c++ - 从构造函数间接调用纯虚函数是否总是未定义的行为?

标签 c++ constructor pure-virtual

我正在构建 Cppcheck在 AIX 上使用 xlC编译器(参见 previous question )。检查器类都派生自 Check类,其构造函数在全局列表中注册每个对象:

check.h

class Check {
public:
    Check() {
        instances().push_back(this);
        instances().sort();
    }
    static std::list<Check *> &instances();
    virtual std::string name() const = 0;
private:
    bool operator<(const Check *other) const {
        return (name() < other->name());
    }
};

checkbufferoverrun.h

class CheckBufferOverrun: public Check {
public:
    // ...
    std::string name() const {
        return "Bounds checking";
    }
};

我似乎遇到的问题是 instances().sort()称呼。 sort()会调用Check::operator<()这叫Check::name()在静态 instances() 中的每个指针上列表,但是 Check刚刚添加到列表中的实例尚未完全运行其构造函数(因为它仍在 Check::Check() 中)。因此,调用 ->name() 应该是未定义的行为。在 CheckBufferOverrun 之前的这样一个指针上构造函数已完成。

这真的是未定义的行为,还是我在这里遗漏了一个微妙之处?

请注意,我不认为调用 sort()是严格要求的,但效果是 Cppcheck 以确定的顺序运行其所有检查器。这只会影响检测到错误的顺序的输出,这会导致某些测试用例失败,因为它们期望以特定顺序输出。

更新:上面的问题仍然(大部分)成立。但是,我认为调用 sort() 的真正原因在构造函数中没有引起问题(即通过调用纯虚函数崩溃)是 Check::operator<(const Check *)从未真正被 sort() 调用过!相反,sort()似乎是比较指针。这发生在g++xlC ,表明 Cppcheck 代码本身存在问题。

最佳答案

是的,它是未定义的。标准在10.4/6中特别这样说

Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.

关于c++ - 从构造函数间接调用纯虚函数是否总是未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4868226/

相关文章:

c++ - 引用变量和虚函数

c++ - 可变参数模板无法识别 constexpr 函数

c++ - 多线程基准

c++ - 初始化列表和 std::forward

c++ - 基类构造器

c++ - 确定方法是否为纯虚拟 (c++)

c++ - 使用 MinGW 编译并安装 FTGL lib 以在 OpenGL 中渲染文本

c++ - 如何将成员声明为指向 extern "C"函数的指针?

c++ - 纹理坐标 OSG GLSL

java - 图书馆和图书类,构造函数