gpt4 book ai didi

c++ - sleep 影响哪个虚拟成员函数被std::thread调用?

转载 作者:可可西里 更新时间:2023-11-01 17:37:45 25 4
gpt4 key购买 nike

我不确定这是否是 c++11 中的预期行为。这是我发现的一个例子。

#include <iostream>
#include <thread>
using namespace std;

class A {
public:
virtual void a() = 0;
thread t;
A() : t(&A::a, this) {}
virtual ~A() {
t.join();
}
};

class B : public A {
public:
virtual void a() {
cout << "B::a" << endl;
}
};

int main() {
B b;
this_thread::sleep_for(chrono::seconds(1));
}

编译运行时

$ g++ -std=c++11 -pthread test.cpp -o test
$ ./test
B::a
$

但是当 sleep 被移除时...

int main() {
B b;
//this_thread::sleep_for(chrono::seconds(1));
}

奇怪的事情发生了

$ g++ -std=c++11 -pthread test.cpp -o test
$ ./test
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
$

这可能是一个错误吗?

最佳答案

在构造函数和析构函数中 virtual 函数的行为不同。在A的构造函数中,B还没有初始化,这就是为什么B的虚函数还不能被调用的原因。参见 virtual :

When a virtual function is called directly or indirectly from a constructor or from a destructor (including during the construction or destruction of the class’s non-static data members, e.g. in a member initializer list), and the object to which the call applies is the object under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class. In other words, during construction or destruction, the more-derived classes do not exist.

因此,该成员函数指针 &A::a 在调用它时在另一个线程中得到解析。此调用解析使用虚拟表,因为 &A::a 是指向虚拟成员函数的指针。构造函数做的第一件事是将虚拟表指针设置为类的虚拟表。如果 B 的构造函数在调用 (this->&A::a)() 时已经进入,则它调用 B::a。在调用 (this->&A::a)() 的新线程与执行 AB 的当前线程之间存在竞争条件构造函数。

关于c++ - sleep 影响哪个虚拟成员函数被std::thread调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49938785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com