现象

程序崩溃,报错:pure virtual method called,terminate called without an active exception,大意为调用了纯虚函数,程序中止。

原因分析

纯虚函数是没有函数体的虚函数。包含纯虚函数的类就叫抽象类。C++不允许抽象类实例化对象,正常情况下不会执行抽象类的纯虚函数。
虚函数通过函数表实现多态,在一些特殊情况下(不安全的代码写法)会发生纯虚函数的调用。

通常情况下在构造和析构的时候容易报"pure virtual method called"错误,这与基类和派生类的构造函数和析构函数的执行顺序有关。
构造函数执行顺序:
1、先初始化基类:将对象的虚函数指针指向基类虚函数表,初始化基类成员变量,调用基类构造函数;
2、再初始化派生类:将对象的虚函数表指针指向派生类虚函数表,初始化派生类成员变量,调用派生类构造函数。

析构顺序和构造顺序相反:
1、先析构派生类:对象的虚表指针指向的是派生类的虚函数表,调用派生类析构函数,执行派生类成员变量的析构;
2、再析构基类:将虚表指针指向基类虚函数表,调用基类析构函数,析构基类成员变量。

根据上面的流程,构造函数和析构函数执行过程中,都有一段时间对象的虚函数指针指向基类虚函数表,如果在构造或者析构没有完成的时候调用了该对象的虚函数,则是调用了基类的纯虚函数。这种情况一般发生在多线程调用,构造或析构在一个线程,虚函数调用在另一个线程。

解决思路

1、在调用对象的函数时,对象指针进行有效性判断(p==NULL);
2、不要再构造函数和析构函数中执行睡眠操作;
3、对对象指针加锁;
4、先停止线程,sleep,再执行析构,留一个时间隔离度,不要在析构函数里停止线程。

Qt复现pure virtual method called报错demo

运行后报错pure virtual method called,terminate called without an active exception,程序crash
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>//基类
class Cheese{public:Cheese(){};virtual ~Cheese(){QThread::msleep(200);};//基类析构函数执行了睡眠virtual void func() = 0;//纯虚函数
};
//派生类
class Cake : public Cheese{public:Cake(){};virtual ~Cake(){};virtual void func(){};//虚函数
};QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);~MainWindow();
private:Ui::MainWindow *ui;Cake *pCake;pthread_t ntid;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <pthread.h>void* thread_func(void* p)
{Cake *tCake = (Cake*)p;delete tCake;return NULL;
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow)
{ui->setupUi(this);pCake = new Cake;pthread_create(&ntid,NULL,thread_func,pCake);//在子线程释放pCakeQThread::msleep(20);//睡眠等待进入析构睡眠//多线程调用时,如果在别的线程执行了析构,当前线程还在继续调用pCake,则会报错//可以做pCake==NULL判断,避免普通的crash//但是如果基类的析构函数执行时间较长(比如在sleep),此时pCake!=NULL,还会执行下面的函数,此时就会pure virtual method calledpCake->func();
}MainWindow::~MainWindow()
{delete ui;
}

Qt复现pure virtual method called报错,与解决办法相关推荐

  1. ibatis mysql 同时删多个表报错_MySQL中Multiple primary key defined报错的解决办法

    MySQL中Multiple primary key defined报错的解决办法 创建主键可以有两种方式: create table 表名( 字段名 类型, 字段名 类型, -- primary k ...

  2. uniapp 云打包后IOS白屏,真机调试也是白屏,没有报错!解决办法

    uniapp 云打包后IOS白屏,真机调试也是白屏,没有报错!解决办法! 原来用uniapp 写的小程序 然后要翻成app 一开始还是很顺利的,因为安卓端测试 没有什么大问题:但是IOS直接白屏,只能 ...

  3. windows10下,from skimage import morphology 报错的解决办法

    windows10下,from skimage import morphology 报错的解决办法 报错原因 没有安装numpy+mkl库 解决方法 卸载skimage pip uninstall s ...

  4. Xamarin开发安装Visual Studio 2015 update2报错的解决办法

    Xamarin开发安装Visual Studio 2015 update2报错的解决办法 错误信息:update 2 requires a member of the visual studio 20 ...

  5. source insight删除保存路径为中文的project工程项目报错的解决办法

    http://blog.csdn.net/yixilee/archive/2010/09/01/5855663.aspx source insight删除已加载的project工程项目报错的解决办法 ...

  6. 图解Myeclipse 导入Java Web项目报错的解决办法听语音

    图解Myeclipse 导入Java Web项目报错的解决办法听语音 https://jingyan.baidu.com/article/046a7b3e953ef3f9c27fa93d.html

  7. 12 c for. oracle rac,【案例】Oracle RAC FOR AIX搭建执行root.sh时两次报错的解决办法

    天萃荷净 运维DBA反映在aix 5.3 ml6安装10.2.0.1 rac报错0509-036 Cannot load program crsctl.bin because of the follo ...

  8. SQLSERVER 创建ODBC 报错的解决办法 SQLState:‘01000‘的解决方案

    SQLSERVER 创建ODBC 报错的解决办法 SQLState:'01000'的解决方案 参考文章: (1)SQLSERVER 创建ODBC 报错的解决办法 SQLState:'01000'的解决 ...

  9. 安装mysql驱动报错_java.sql.SQLException: org.gjt.mm.mysql.Driver 报错【解决办法】

    今天爱分享给大家带来java.sql.SQLException: org.gjt.mm.mysql.Driver 报错[解决办法],希望能够帮助到大家. spring boot mysql 中启动报错 ...

最新文章

  1. ACE_Service_Handler类的理解和使用
  2. kill linux 信号量,kill用法详细解释(特别是信号量9的使用以及理解)
  3. Dispatch Queue 之 Invoke 当前队列
  4. C# Lazy Loading
  5. Redis解决秒杀中的超卖问题
  6. CSS之Bootstrap(快速布局)
  7. 中国网络空间安全协会成立 永信至诚等200家单位共建网络安全
  8. 「SAP技术」SAP MM 启用了MPN物料管理的物料,物料主数据与源清单数据有啥不同?
  9. linux服务器时间不一致,Linux服务器时间不准确
  10. 蓝牙模块有哪些种类?BLE低功耗蓝牙模块有什么特点?
  11. 手机连接电脑DCIM目录下文件夹和图片显示不全
  12. 基于Matlab的机器人学建模学习资料大整理
  13. Educoder---Java继承与接口、文件
  14. Qt 官方例子 Callout Example
  15. 使用 github copilot 踩坑记录:failed to initiate the github login process please try again
  16. (二)51单片机基础——LED
  17. Hunter’s Apprentice (猎人的学徒)——【Green 公式( 判断多边形边界曲线顺/逆时针】
  18. ListView动态刷新
  19. 如何设计一个网页爬虫
  20. macOS 安装PhotoshopCC 2017

热门文章

  1. LeetCode:309. 最佳买卖股票时机含冷冻期(python)
  2. 在vue中实现picker样式_vue中van-picker的多列联动数据格式如何设置以及调用
  3. 【NOIP2013模拟】粉刷匠
  4. Elasticsearch分析器(analyzer)以及与spring boot整合
  5. 相机光学(十八)——MTF与SFR
  6. R语言ggplot2可视化:使用patchwork包的align_patches函数将多个可视化图像对齐(align all plots)
  7. Macbook Pro 外接显卡实现Tensorflow GPU运行之环境配置(重点)
  8. Ubuntu1804换源
  9. C语言%p与%x的区别
  10. 虚拟机(Ubuntu18.04版本)中文字体乱码或混乱的一种解决方案