Qt 每日面试题 -7

61、如何安全的在另外一个线程中调用QObject对象的接口

QObject被设计成在一个单线程中创建与使用,因此,在一个线程中创建一个对象,而在另外的线程中调用它的函数,这样的行为不能保证工作良好。使用信号槽的队列连接或者QT的反射系统提供的QMetaObject::invokeMethed的队列连接调用。这要求接口必须是内省的,也就是说这个函数要么是一个槽函数,要么标记有Q_INVOKABLE宏。将事件提交到接收对象所在线程的事件循环;当事件发出时,响应函数就会被调用。

62、槽函数的参数是否可以比信号的参数多?

也可以。唯一的情况就是槽函数参数带有默认参数,除去默认参数外,槽函数的参数必须小于等于信号的参数。

63、指针和引用有什么区别? 什么情况下用指针? 什么情况下用引用?

区别:

  1. 指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元,即指针是一个实体;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。
  2. 指针有const指针,但是引用没有const引用。
  3. 指针可以有多级,但是引用只能是一级( int** p;合法,而int&& a;不合法)。
  4. 指针的值可以为空,但是引用的值不可以,并且引用在定义的时候必须初始化。
  5. 指针的值在初始化后可以改变,即指向其它的存储单元,而引用在初始化后就不会再改变了,从一而终。
  6. sizeof(引用) 得到的是所指向的变量(对象)的大小,而sizeof(指针) 得到的是指针本身的大小。
  7. 指针和引用的自增++运算意义不一样。

相同点:

  1. 都可以对变量就行修改。
  2. 都是地址的概念,指针指向一块内存,它的内容是所指内存的地址,引用是某块内存的别名。

何时使用︰

  1. 当考虑到存在不指向任何对象的可能,这时候应该使用指针。
  2. 当需要在能够在不同的时刻指向不同的对象,这个时候使用指针。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么应该使用引用。
  3. 当重载某个操作符时,应该使用引用。

64、一般什么情况下会出现内存泄漏?怎么用C++在编码层面尽量避免内存泄漏。

内存泄漏是指程序向系统申请分配内存使用(new),用完以后却没有归还(delete)。结果申请的那块内存程序不再使用,而系统也无法再讲它分配给需要的程序。

造成内存泄漏的几种情况∶

  1. 指针重新赋值
  2. 错误的内存释放
  3. 返回值的不正确处理
  4. new和delete没有配对使用

如何避免内存泄漏∶

  1. 确保没有访问空指针
  2. 尽量使用智能指针
  3. new和delete配对使用

65、对C++11的智能指针了解多少,可以自己实现一个智能指针吗?

三种智能指针∶

  • std::shared_ptr : 使用引用计数,每一个shared_ptr的拷贝都指向相同的内存,每次拷贝都会触发引用计数+1,每次生命周期结束析构的时候引用计数-1,在最后一个shared_ptr析构的时候,内存才会释放。
  • std::weak_ptr : 用来监视shared_ptr的生命周期,它不管理shared_ptr内部的指针,它的拷贝析构都不会影响引用计数,纯粹是作为一个旁观者监视shared_ptr中管理的资源是否存在,可以用来返回this指针和解决循环引用问题。
  • std::unique_ptr : 独占型的智能指针,它不允许其它智能指针共享其内部指针,也不允许unique_ptr的拷贝和赋值。

66、show()和exec()的区别

  • show显示非模态窗口(不影响用户对其他窗口操作)
  • exec显示模态窗口(阻塞其他窗口,必须在当前窗口操作完成后才能访问其他窗口)
  • open半模态(阻塞其他窗口响应,但不影响后续代码执行)

67、Qt事件循环

Qt的主事件循环能够从事件队列中获取本地窗口系统事件,然后判断事件类型,并将事件分发给特定的接收对象。

主事件循环通过调用QCoreApplication::exec()启动,随着QCoreApplication::exit()结束,本地的事件循环可用利用QEventLoop构建。

68、什么叫自定义控件

qt本身的控件不能满足需求将原控件功能提升达到要求,此时控件为自定义控件。

69、讲一下Qt的D指针(d_ptr )和Q指针(q_ptr )?

  • D指针
    PIMPL模式,指向一个包含所有数据的私有数据结构体
    私有的结构体可以随意改变,而不需要重新编译整个工程项目
    隐藏实现细节
    头文件中没有任何实现细节,可以作为API使用
    原本在头文件的实现部分转移到乐源文件,所以编译速度有所提高

  • Q指针
    私有的结构体中储存一个指向公有类的Q指针。

总结:

  • Qt中的一个类常用一个PrivateXXX类来处理内部逻辑,使得内部逻辑与外部接口分开,这个PrivateXXX对象通过D指针来访问;在PrivateXXX中有需要引用Owner的内容,通过Q指针来访问。
  • 由于D和Q指针是从基类继承下来的,子类中由于继承导致类型发生变化,需要通过static_cast类型转化,所以DPTR()与QPTR()宏定义实现了转换。

70、Qt信号槽的调用流程

  • MOC查找头文件中的signal与slots,标记出信号槽。将信号与槽信息储存到类静态变量staticMetaObject中,并按照声明的顺序进行存放,建立索引。
  • connect链接,将信号与槽的索引信息放到一个双向链表中,彼此配对。
  • emit被调用,调用信号函数,且传递发送信号的对象指针(元对象指针),通过信号索引将参数列表传到active函数。
  • active函数在双向链表中找到所有与信号对应的槽索引,根据槽索引找到槽函数,执行槽函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江凡心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值