Qt信号槽中槽函数为虚函数的一些感想
有时候,在写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信号槽中槽函数为虚函数的一些感想的更多相关文章
- qt信号signal和槽slot机制
内容: 一.概述 二.信号 三.槽 四.信号与槽的关联 五.元对象工具 六.程序样例 七.应注意的问题 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工 ...
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- C++中的多态与虚函数的内部实现
1.什么是多态 多态性可以简单概括为“一个接口,多种行为”. 也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可 ...
- C++中不能声明为虚函数的有哪些函数
常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被o ...
- C++中的纯虚函数和虚函数的作用
1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class) ...
- 转 C++中不能声明为虚函数的有哪些函数
传送门 C++中不能声明为虚函数的有哪些函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数 ...
- C++中的继承与虚函数各种概念
虚继承与一般继承 虚继承和一般的继承不同,一般的继承,在目前大多数的C++编译器实现的对象模型中,派生类对象会直接包含基类对象的字段.而虚继承的情况,派生类对象不会直接包含基类对象的字段,而是通过一个 ...
- C++ 中不能声明为虚函数的函数有哪些?
目录 普通函数 构造函数 内联成员函数 静态成员函数 友元函数 普通函数 普通函数(非成员函数)只能被overload,不能被override,而且编译器会在编译时绑定函数. 多态的运行期行为体现在虚 ...
- C++中如何实现像Java中接口功能--C++抽象类(纯虚函数,虚函数)
在Java中定义个接口,之后可以定义不同的类来实现接口,如果有个函数的参数为这个接口的话,就可以对各自的类做出不同的响应. 如: interface animal { public void info ...
- C++中的多态及虚函数大总结
多态是C++中很关键的一部分,在面向对象程序设计中的作用尤为突出,其含义是具有多种形式或形态的情形,简单来说,多态:向不同对象发送同一个消息,不同的对象在接收时会产生不同的行为.即用一个函数名可以调用 ...
随机推荐
- weblogic启动报错之未修改hosts产生错误
报错如下: Enter username to boot WebLogic server:weblogic Enter password to boot WebLogic server: <Ju ...
- ab压测 apr_socket_recv: Connection reset by peer (104)错误解决方法
用apache自带ab命令进行压测,报了如下错误: 原因是在ab的程序源码中对并发数有限制. 解决办法:修改apache源码support下面的ab.c源代码,然后重新编译.修改内容如下:
- HDU 5875 Function 【倍增】 (2016 ACM/ICPC Asia Regional Dalian Online)
Function Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- 【模拟】Vijos P1005 超长数字串
题目链接: https://vijos.org/p/1005 题目大意: 无限的正整数按顺序拼接成字符串S(S=12345678910111213...),给你一个字符串A(len<=200)求 ...
- HDOJ 2014 青年歌手大奖赛_评委会打分
Problem Description 青年歌手大奖赛中,评委会给参赛选手打分.选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分. Input 输入数据有多组,每组占 ...
- 《C专家编程》读书笔记
第一章 const float* 表示一个指向float类型常量的指针 第二章 1. 在c语言中const并非真正表示“常量”,在数组定义与case中不可以使用 2. case的一些问题 1: #in ...
- 高性能Java Web 页面静态化技术(原创)
package com.yancms.util; import java.io.*; import org.apache.commons.httpclient.*; import org.apache ...
- MYSql查詢一段時間記錄
24小时内记录(即86400秒) $sql="SELECT video_id,count(id)as n FROM `rec_down` WHERE UNIX_TIMESTAMP(NOW() ...
- android使用bintray发布aar到jcenter
前言 这两天心血来潮突然想把自己的android library的aar放到jcenter里面,这样一来自己便可以在任何时间任何地点通过internet得到自己的library的引用了,况且现在and ...
- 《HTML5 从入门到精通--7.6.3 单元格垂直跨度——rowspan》
单元格除了能够在水平方向上跨列,还能够垂直方向上跨行.跨行设置须要使用rowspan參数. 语法 <td rowspan="单元格跨行数"> 语法解释 与水平跨度相相应 ...