c++继承:当虚方法被重写时调用它
C++ Inheritance : Calling virtual method when it has been overridden
我试图建立一个service
对象,可以运行(即执行它的run()
函数)在一个单独的线程。这是服务对象
#include <boost/noncopyable.hpp>
#include <atomic>
#include <thread>
#include <iostream>
class service : public boost::noncopyable {
public:
service() : stop_(false), started_(false) { }
virtual ~service() {
stop();
if (thread_.joinable()) {
thread_.join();
}
}
virtual void stop() { stop_ = true; }
virtual void start() {
if (started_.load() == false) {
started_ = true;
thread_ = std::thread([&] () {
run();
});
}
}
protected:
virtual void run() = 0;
std::atomic<bool> stop_;
std::atomic<bool> started_;
std::thread thread_;
};
我正在创建一个test
类,它继承了这个抽象类,并在main()
函数中调用
class test : public service {
public:
test() : service() {
std::cout<< "CTOR" << std::endl;
start();
}
~test() {
std::cout<< "DTOR" << std::endl;
}
protected:
void run() override {
std::cout << "HELLO WORLD" <<std::endl;
}
};
int main() {
test test1;
return 0;
}
现在当我执行这个,为什么我得到一个错误说pure virtual function called
?run()
函数显然在test
类中被重写了。更糟糕的是,它有时运行正确?
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
$ ./a.out
CTOR
DTOR
HELLO WORLD
$ ./a.out
CTOR
DTOR
pure virtual method called
terminate called without an active exception
这里可能出了什么问题?
跟着做,一步一步来:
1)你构造对象。
2)执行以下代码:if (started_.load() == false) {
started_ = true;
thread_ = std::thread([&] () {
run();
});
}
父线程立即返回main()
,在那里它立即退出并销毁你的对象。
这是你的bug:
- 您不能保证在父线程终止进程之前,在
start()
中启动的线程将到达对run()
的调用。子线程和父线程同时运行。
所以,每隔一段时间,父线程会在子线程启动之前销毁对象,并调用run
()。
此时,调用run
()方法的对象已经被销毁。
未定义的行为。
每隔一段时间,你正在点击的断言是这种未定义行为的一个可能结果。
相关文章:
- 如何强制从重写方法调用重写的方法基方法?
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- C++调用使用重写函数的父类函数
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 从基类调用重写的方法
- 重写require后调用"lua_getfield()"时崩溃
- 哪个基类调用派生重写的方法?
- 如何在子类中重写时调用私有虚拟基类实现
- 调用不是来自直系父亲的重写方法
- 为什么继承的函数忽略了在原始函数中调用的重写函数?
- Qt/C++ - 从派生类调用重写方法
- 重写运算符 [] 和调用方法
- 继承和重写 - 从基类调用重写子方法
- 正在接口构造函数中调用重写的接口方法
- 如何在向量上调用不同的重写方法
- 如果基方法不是虚拟方法,则调用重写的方法
- 调用重写函数并使用基类中的重载变量
- 从基类调用重写的方法
- 从其基类列表中调用重写的函数
- 如何重写调用另一个抽象类的抽象类的虚拟函数