如果
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;
}
这将产生未定义的行为。
虽然我认为该标准目前缺乏一些措辞,但我认为只有在最派生对象的构造完成后才可以在另一个线程中使用该对象。
当尝试通过不是从 this
派生的指针访问对象时,
[class.cdtor]/2中给出了类似的规定。
我还希望类是否是多态的并不重要。上面链接的限制也不仅仅适用于多态类。