有时候,在写connect的时候会去犹豫一个问题----我的槽函数到底需不需要为虚函数。这个问题在我每次写connect的时候我都会反问自己,因为确实,如果你不去深究里面的moc,你发现不了太多问题。

比如有这么一个demo.

#include <QApplication>
#include <QObject>
#include <QDebug>class Test : public QObject
{Q_OBJECT
public:void onEmit() {emit test();}
signals:void test();
};class Base : public QObject
{Q_OBJECT
public:Base(Test *p) {this->p = p;connect(p,SIGNAL(test()), this, SLOT(onTest()));}void testConnect() {//    connect(p,SIGNAL(test()), this, SLOT(onTest()));
    }private slots:void onTest() {qDebug() << "This is Base's test";}
private:Test *p;
};class Child : public Base
{Q_OBJECT
public:Child(Test *p) : Base(p){}
private slots:void onTest() {qDebug() << "This is Child's test";}
};
int main(int argc, char **argv)
{Test t;Base *b = new Child(&t);b->testConnect();t.onEmit();return 0;
}#include "main.moc"

简单的来说,很多人会习惯性的在基类构造函数的时候建立connect机制,但这个时候,由于Effective C++中有一条不推荐在构造函数和析购函数中使用虚函数,这里明确可以说明出,在Base中的connect,如果你不是另外调用一把testConnect,而是直接写在构造函数中,这个时候connect中的this虽然地址和Child是一致,但这个时候如果你用typeid可以发现在创建Child的时候经过Base构造函数的时候,connect的this的类型是Base,而就在此时,moc文件会去选择用Base::metaObject,而不是去用Child::metaObject去和Test的信号关联。这个时候会出现什么问题?没错,基类指针指向子类类型,在你槽函数没进行虚函数的情况下,你虽然以为connect会去调用你子类的槽函数,但实际情况是,基类指针仍旧去调用基类函数。所以,在构造函数中写connect的务必把槽函数设置成虚函数。

当然了,你也可以不在构造函数中进行connect,而专由testConnect这类的函数在对象构造好之后再去链接,这个时候,metaObject会选择你创建的正确类型,这个时候的槽函数不管你虚还是不虚,对会去调用当前真正指向的类型(包括子类情况,或者基类指针指向子类情况,都会去调用子类的槽函数),所以请谨慎注意构造函数中的connect.

转载于:https://www.cnblogs.com/rickyk/p/3835695.html

Qt信号槽中槽函数为虚函数的一些感想相关推荐

  1. [转载]qt信号signal和槽slot机制

    好东西! 原文地址:qt信号signal和槽slot机制作者:fox1987 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工具以及在实际使用过程中应注 ...

  2. C++多继承中重写不同基类中相同原型的虚函数

    在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA  {  public:  virtual void TestA();  };  class ...

  3. C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中

    C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中 测试2:证明派生类的虚函数的地址跟第一基类的虚函数地址保存在同一张虚函数表中. 派生类有多少个拥有虚函数的基类,派生类对象就有多少 ...

  4. 为什么构造函数不能声明为虚函数,析构函数可以,构造函数中为什么不能调用虚函数?

    为什么构造函数不能声明为虚函数,析构函数可以,构造函数中为什么不能调用虚函数 构造函数中为什么不能调用虚函数? 第一个理由是概念上的 第二个理由是机械上的. 构造函数不能声明为虚函数的原因是 1 构造 ...

  5. C++继承中的普通函数,纯虚函数、虚函数

    继承中的普通函数,纯虚函数.虚函数 C++ 在继承中虚函数.纯虚函数.普通函数,三者的区别 普通函数(no-virtual) 纯虚函数(pure virtual) 虚函数(impure virtual ...

  6. C++中的继承与虚函数各种概念

    虚继承与一般继承 虚继承和一般的继承不同,一般的继承,在目前大多数的C++编译器实现的对象模型中,派生类对象会直接包含基类对象的字段.而虚继承的情况,派生类对象不会直接包含基类对象的字段,而是通过一个 ...

  7. C++中不能声明为虚函数的有哪些函数

    常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被o ...

  8. 面试中常被问到(11)虚函数/纯虚函数

    虚函数 如何定义一个虚函数?在基类成员函数前加入virtual关键字,但并不代表此函数不被实现,只是说明允许基类指针调用派生类重写的此函数 一个类只要声明有虚函数或者从基类继承了虚函数,在编译过程中就 ...

  9. c语言中虚函数和纯虚函数,C++ 虚函数和纯虚函数的区别

    首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...

  10. 【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 )

    文章目录 类的继承 方法的重写 子类中调用父类方法 多态 虚函数 虚函数示例 纯虚函数 相关代码 类的继承 1. 继承表示 : C++ 中继承可以使用 ":" 符号 , 格式为 & ...

最新文章

  1. 乘风破浪:LeetCode真题_007_Reverse Integer
  2. Windows内核系统调用分析
  3. mongodb连接失败_MongoDB 基础入门
  4. VS中怎样对C#项目进行单元测试
  5. 初识powershell、nuget powershell 调试
  6. Redis安装部署配置说明
  7. ArcGIS API for JavaScript 4.0(一)
  8. 数据库-优化-索引-索引的优化
  9. 世界十大最有价值公司(1997-2019)
  10. 转: 自适应css布局—-流动布局新时代(译文)
  11. mysql查询结果更新到新表_MySQL查询结果复制到新表的方法(更新、插入)
  12. AAAI 2019 使用循环条件注意力结构探索回答立场检测任务
  13. python——decimal模块
  14. vb mysql数据库连接,VB连接Mysql数据库
  15. 轻巧和实用并存——360安全卫士极速版试用报告
  16. 一款免费好用的在线高效作图工具
  17. 魔兽世界国服服务器稳定,《魔兽世界》国服大服务器功能实装启动
  18. oracle 19c pdb cdb,12c、19c 从 no-cdb升级到pdb步骤
  19. [技术分享 – FCS 篇] 驭龙五式3之飞龙在天:安装 FCS 服务器
  20. 项目经理面试问题整理与技巧分析

热门文章

  1. opencv 2d直方图
  2. python svm 实战_opencv-python 入门实战:传统方法Hog+svm实现目标检测
  3. linux进程及作业管理实验,Linux 进程及作业管理(一)
  4. Exchange邮件系统日志查看及管理
  5. Java基础学习总结(79)——Java本地接口JNI详解
  6. 湖南单招计算机专业大学排名,2021湖南单招学校排名及分数线:湖南单招分数线高吗?...
  7. linux系统克隆安装教程,使用Clonezilla克隆Linux安装的方法
  8. informix多张表UPDATE时不能用别名
  9. 拆轮子系列--RxJava理解(一)--Map解析
  10. eslint的安装与使用