在基类构造函数中创建的 lambda 在调用虚函数时会导致 vtable 上的数据争用吗?

问题描述 投票:0回答:1

如果

ipc
在单独的线程上调用 lambda,那么这段代码中是否存在数据竞争?如果 vtable 尚未完全构建,那么 lambda 可能会调用
Base::Handler()
,但如果是,那么它将调用
Derived::Handler()
,对吧?我注意到,如果我将 lambda 分配给 Base 的
std::function
公共成员并在构建
d
后调用它,那么代码会打印“Derived”。

#include <thread>
#include <chrono>
#include <functional>
#include "IPC.h"

struct Base {
    Base() {
        ipc.SetHandler([this]{ Handler(); });
        // Handler(); // would call Base::Handler() here
    }
    virtual ~Base() {}
    virtual void Handler() { std::cout << "Base" << std::endl; }
    IPC ipc; // uses boost's io_service, btw
};

struct Derived : public Base {
    Derived() : Base() {}
    void Handler() override { std::cout << "Derived" << std::endl; }
};

int main()
{
    // plenty of code
    // ...
    Derived d = Derived();
    // much more code
    // ...
    return 0;
}
c++ inheritance undefined-behavior race-condition
1个回答
0
投票

这将产生未定义的行为。

虽然我认为该标准目前缺乏一些措辞,但我认为只有在最派生对象的构造完成后才可以在另一个线程中使用该对象。

当尝试通过不是从 this 派生的指针访问对象时,

[class.cdtor]/2
中给出了类似的规定。

我还希望类是否是多态的并不重要。上面链接的限制也不仅仅适用于多态类。

© www.soinside.com 2019 - 2024. All rights reserved.