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++中很关键的一部分,在面向对象程序设计中的作用尤为突出,其含义是具有多种形式或形态的情形,简单来说,多态:向不同对象发送同一个消息,不同的对象在接收时会产生不同的行为.即用一个函数名可以调用 ...
随机推荐
- Git基本操作(Windows下)
在开始使用Git之前,我觉得是很有必要了解下Git与其他版本控制系统的差异与文件在Git中的三种状态.可以到下面这个网站看下:Git详解之一 Git起步,了解之后,可以对Git的基本操作有一个更清晰的 ...
- selenuim ide回放时出现的问题
[error] Unexpected Exception: fileName -> chrome://selenium-ide/content/selenium-core/scripts/htm ...
- Agri-Net(prim算法,最小生成树问题)
看图便知道: 来来上代码: #include <cstdio>#include <cstdlib>#include <cstring>#includ ...
- 路由器刷机常见第三方固件及管理前端种类(OpenWrt、Tomato、DD-Wrt)
目前路由器折腾刷机,除了采用各品牌的原厂固件外,第三方路由器固件,基本就是:Tomato.DD-WRT.OpenWRT三种. 基本上所有第三方路由器固件的架构上可分为前端(Frontend)和后端(B ...
- Eclipse : 找不到或无法加载主类
问题: 找不到或无法加载主类 解决思路: Step1: 去网上百度了下,基本上都说是环境变量的问题. 原因:环境变量设置有问题. 解决方法:重设环境变量 结果:当然问题没解决. Step2:再次百度, ...
- Apache HBase 2015年发展回顾与未来展望
编者按:高可用架构推出 2015 年度回顾系列文章,分享在架构领域具有典型意义的年度案例,本文由张虔熙分享.转载请注明来自高可用架构公众号「ArchNotes」. 张虔熙,Hulu 网,专注于分布 ...
- 6种GET和POST请求发送方法
我试过了畅言和多说两种社会化评论框,后来还是抛弃了畅言,不安全. 无论是畅言还是多说,我都需要从远程抓取文章的评论数,然后存入本地数据库.对于多说,请求的格式如下: // 获取评论次数,参数是文章ID ...
- linux安装vnc
1. 安装vnc-server yum install vnc-server redhat的iso文件中自带 tigervnc-server 2.设置vnc密码 切换到oracle用户,之后再运行vn ...
- [转]windows10 64位环境下安装mysql5.7.17
今天以zip模式在windows10 64位环境下安装mysql5.7,到最后一步提示mysql服务无法启动. 安装步骤如下: 1.配置环境变量 我的电脑->属性->高级->环境变量 ...
- C语言学习_从VC++6.0开始
前言: C语言是一门博大精深的语言,C语言往往是程序员以及所有软件行业从业者的第一门编程语言. 编程环境: 对于初学者来说,我一开始学习C语言,其实是用的turboc 2.0版本,这个很有历史感,但是 ...