有时候,在写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 ;
} #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.

Qt信号槽中槽函数为虚函数的一些感想的更多相关文章

  1. qt信号signal和槽slot机制

    内容: 一.概述 二.信号 三.槽 四.信号与槽的关联 五.元对象工具 六.程序样例 七.应注意的问题 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工 ...

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

    本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...

  3. C++中的多态与虚函数的内部实现

    1.什么是多态         多态性可以简单概括为“一个接口,多种行为”.         也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可 ...

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

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

  5. C++中的纯虚函数和虚函数的作用

    1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class) ...

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

    传送门 C++中不能声明为虚函数的有哪些函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数 ...

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

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

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

    目录 普通函数 构造函数 内联成员函数 静态成员函数 友元函数 普通函数 普通函数(非成员函数)只能被overload,不能被override,而且编译器会在编译时绑定函数. 多态的运行期行为体现在虚 ...

  9. C++中如何实现像Java中接口功能--C++抽象类(纯虚函数,虚函数)

    在Java中定义个接口,之后可以定义不同的类来实现接口,如果有个函数的参数为这个接口的话,就可以对各自的类做出不同的响应. 如: interface animal { public void info ...

  10. C++中的多态及虚函数大总结

    多态是C++中很关键的一部分,在面向对象程序设计中的作用尤为突出,其含义是具有多种形式或形态的情形,简单来说,多态:向不同对象发送同一个消息,不同的对象在接收时会产生不同的行为.即用一个函数名可以调用 ...

随机推荐

  1. 网络流(最大费用最大流) :POJ 3680 Intervals

    Intervals Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7218   Accepted: 3011 Descrip ...

  2. Delphi NativeXml用法攻略 转

    NativeXml可以在官网上下载,下载后将文件夹放在指定地方,打开DELPHI在其环境变量中引用NativeXml路径,然后在程序中引用NativeXml单元,我们就可以使用NativeXml了. ...

  3. 面向新手的Webserver搭建(一)——IIS的搭建

    非常多童鞋说自己是做移动开发的,想挂个简单的Web API,但是server又不会搭,这样一来測试就成了问题.看看网上的教程.发现略难懂,并且大多是一个转一个,没价值,所以干脆写几篇文章讲讲简单的We ...

  4. poj--1579--(DFS+记忆化搜索之经典)

    记忆化搜索   记忆化搜索:算法上依然是搜索的流程,但是搜索到的一些解用 动态规划的那种思想和模式作一些保存. 一般说来,动态规划总要遍历所有的状态,而搜索可以排除一些无效状态. 更重要的是搜索还可以 ...

  5. Etcd学习(一)安装和.NETclient測试

    Etcd是一个比較新的分布式协调框架,由CoreOS的开发团队开发,如今才仅仅到0.4.6版本号,还没公布1.0版本号 我看了一下GitHub上作者们的提交记录,如今应该还在如火如荼的开发以及改动Bu ...

  6. digoal -阿里云postgrel大神

    https://yq.aliyun.com/users/1384833841157402?spm=5176.100239.blogrightarea51131.3.T5LRsF

  7. c++回调编程本质

    1. boost:bind获得一个函数对象,就像函数指针一样,这个行为可以作为回调 2. bosot:bind的函数对象可以保存别的对象的引用,回调对象的成员函数 3. boost:function是 ...

  8. iOS网络HTTP、TCP、UDP、Socket 知识总结

    OSI 七层模型 我们一般使用的网络数据传输由下而上共有七层,分别为物理层.数据链路层.网络层.传输层.会话层.表示层.应用层,也被依次称为 OSI 第一层.第二层.⋯⋯. 第七层. 如下图: 各层功 ...

  9. Android系统移植与驱动开发--第四章

    第四章 源代码的下载和编译 一个android内核相当于4G,而一个Linux内个只有几百M,Linux内核相对于android内核来说实在是小巫见大巫.了解android源代码不一定要详细了解,只去 ...

  10. 0_Linux_虚拟机安装

    虚拟机的安装0Snapshot和clone 系统分区(由硬盘的性能所限制的) 1分区类型: 主分区:最多有4个 扩展分区:最多只能有1个:主分区加扩展分区最多有4个:不能写入数据,只能包含逻辑分区,不 ...