在源码中,我们会经常看到Q_Q 和 Q_D 这两个东西 ,很好奇,就去网上搜索了一些和 查看了一些源码 部分

一:Q_D相关宏

#define Q_D(Class) Class##Private * const d = d_func()Q_D(Test);
//展开后  是一个  私有类的指针常量
TestPrivate * const d = d_func();

有人不知道“##” 是什么意思,其实就是一个连接符 将A##B -》 AB 组成一个新的字符串名称

Q_DECLARE_PRIVATE(Class)

#define Q_DECLARE_PRIVATE(Class) \inline Class##Private* d_func() \{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \inline const Class##Private* d_func() const \{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \friend class Class##Private;Q_DECLARE_PRIVATE(Test)
//展开后inline TestPrivate* d_func() {return reinterpret_cast<TestPrivate *>(qGetPtrHelper(d_ptr));}inline const TestPrivate* d_func() const{return reinterpret_cast<const TestPrivate *>(qGetPtrHelper(d_ptr));}friend class TestPrivate;

d_ptr 指针:在主类里面写,来访问我们的私有类

二:Q_Q相关宏

#define Q_Q(Class) Class * const q = q_func()Q_Q(Test);
//展开后
Test* const q = q_func();

Q_DECLARE_PUBLIC(Class)

#define Q_DECLARE_PUBLIC(Class)                                    \inline Class* q_func() { return static_cast<Class *>(q_ptr); } \inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \friend class Class;Q_DECLARE_PUBLIC(Test)
//展开后:inline Test* q_func() { return static_cast<Test*>(q_ptr); } inline const Test* q_func() const { return static_cast<const Test*>(q_ptr); } friend class Test;

q_ptr 指针:在私有类 里面写,来访问我们的主类

使用这两个指针的好处:
1.保证代码的二进制兼容性;
二进制兼容性:动态链接到库的前一个版本的程序继续与库的新版本一起运行而不需要重新编译,则库是二进制兼容的。
要能够实现二进制兼容,就要求每一个结构以及每一个对象的数据模型保持不变。所谓“数据模型保持不变”,就是不能在类中增加、删除数据成员
2.隐藏实现细节;

3.提高编译速度

QQAndQDTest.h

#pragma once#include <QtWidgets/QWidget>
#include <QObject>class QQAndQDTestPrivate;
class QQAndQDTest : public QObject
{Q_OBJECTpublic:QQAndQDTest(QObject*parent = Q_NULLPTR);~QQAndQDTest();public:void showMsg();void setValue(int value);int getValue();private:QQAndQDTestPrivate* const d_ptr;Q_DECLARE_PRIVATE(QQAndQDTest)
};class QQAndQDTestPrivate : public QObject
{Q_OBJECTpublic:QQAndQDTestPrivate(QQAndQDTest* q, QObject* parent = Q_NULLPTR);~QQAndQDTestPrivate();void testFunc();
public:QQAndQDTest* const q_ptr;Q_DECLARE_PUBLIC(QQAndQDTest)int m_value;};

QQAndQDTest.cpp

#include "QQAndQDTest.h"
#include <QDebug>
QQAndQDTest::QQAndQDTest(QObject*parent): QObject(parent), d_ptr(new QQAndQDTestPrivate(this))
{}QQAndQDTest::~QQAndQDTest()
{Q_D(QQAndQDTest);delete d_ptr;
}void QQAndQDTest::showMsg()
{Q_D(QQAndQDTest);qDebug() << d->m_value;
}void QQAndQDTest::setValue(int value)
{Q_D(QQAndQDTest);d->m_value = value;
}int QQAndQDTest::getValue()
{Q_D(QQAndQDTest);return d->m_value;
}QQAndQDTestPrivate::QQAndQDTestPrivate(QQAndQDTest* q, QObject* parent): QObject(parent), q_ptr(q), m_value(0)
{}QQAndQDTestPrivate::~QQAndQDTestPrivate()
{delete q_ptr;
}void QQAndQDTestPrivate::testFunc()
{Q_Q(QQAndQDTest);q->showMsg();
}

main.cpp

#include "QQAndQDTest.h"
#include <QtWidgets/QApplication>
#include <QDebug>int main(int argc, char *argv[])
{QApplication a(argc, argv);QQAndQDTest t;t.setValue(10);t.showMsg();return a.exec();
}

我们将值放在 主类的私有类中 ,通过d指针来访问,设置该值 和 获取该值

参考博客:
Q_Q 和 Q_D相关介绍
Q_Q 和 Q_D相关例子
Q_Q 和 Q_D相关说明
Q_Q和Q_D

QT笔记——Q_Q 和Q_D 学习相关推荐

  1. C++学习(一五零)qt的公有类、私有类、Q_Q、Q_D、二进制兼容

    1.二进制兼容 如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的. 如果不能保证库的二进制兼容性,就意味着每次发布库的新版本时, ...

  2. 【QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结】

    [QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结] 1.概述 2.实验环境 3.参考资料-致谢 4.自我提升+实验效果 5.代码练习-学习后拆解 (1)头文件部分 (2)绘制事件+绘制表 ...

  3. Hadoop学习笔记—18.Sqoop框架学习

    Hadoop学习笔记-18.Sqoop框架学习 一.Sqoop基础:连接关系型数据库与Hadoop的桥梁 1.1 Sqoop的基本概念 Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据 ...

  4. JavaScript学习笔记(十)——学习心得与经验小结

    JavaScript学习笔记(十)--学习心得与经验小结 目前我先列好提纲,利用每晚和周末的闲暇时间,将逐步写完 ^_^ 转载于:https://www.cnblogs.com/mixer/archi ...

  5. oracle 百万记录 cache,学习笔记:通过案例深入学习In-Memory Database Cache 总结配置过程...

    天萃荷净 详细记录关于In-Memory Database Cache配置方法与使用案例 一.Oracle数据库创建相关用户和权限 1.创建timesten用户 store information a ...

  6. Hadoop学习笔记—15.HBase框架学习(基础知识篇)

    Hadoop学习笔记-15.HBase框架学习(基础知识篇) HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase ...

  7. Hadoop学习笔记—16.Pig框架学习

    Hadoop学习笔记-16.Pig框架学习 一.关于Pig:别以为猪不能干活 1.1 Pig的简介 Pig是一个基于Hadoop的大规模数据分析平台,它提供的SQL-LIKE语言叫Pig Latin, ...

  8. Notion Like 笔记软件使用教程·学习资源汇总·知识管理方案

    Notion Like 笔记软件使用教程·学习资源汇总·知识管理方案:深度评测.辅助工具.信息管理.时间管理.任务管理.思维管理.项目管理.文件管理.笔记方法.记忆方法.写作方法 关于 Notion ...

  9. 机器学习笔记——神经网络与深度学习

    机器学习笔记--神经网络与深度学习 一.神经网络引言 二.神经元模型与激活函数 2.1 神经元模型 2.2 激活函数 2.2.1 sigmoid & tanh 2.2.2 ReLU激活函数 2 ...

最新文章

  1. hdu4772 水模拟
  2. newman的键盘不错
  3. 谈谈为什么我们需要云原生架构?
  4. linux 安全审计功能,数据库安全审计在数据安全中的功能
  5. 13 - java包装类
  6. Android基础之用Eclipse搭建Android开发环境和创建第一个Android项目(Windows平台)...
  7. ArcMAP 空间连接和相交工具使用
  8. RDCMan 安装问题
  9. 一年增加1.2w星,它能否引领中间件的未来?
  10. 人工智能革命:人类会永生还是灭亡(下)
  11. 关于神经网络中的shape问题
  12. Git学习-本地版本库的创建与简单操作
  13. [原] Python 根据设备编号获取设备名称
  14. 《经济的律动》书中的精髓:如何通过“去杠杆”和“互联网金融”现象,更好地理解经济发展的方向?
  15. C# 学习笔记:委托(5):可变性
  16. 【Ubuntu20安装aria2以及配置web端】
  17. Nginx页面报错404及解决办法
  18. 光伏电站的系统组成及工作原理
  19. 东华大学计算机年薪,东华大学毕业生薪酬高吗?东华大学什么专业工资高 毕业生就业率...
  20. Qt 快速入门系列教程

热门文章

  1. 企业大数据价值最大化的关键因素——内存多维数据库
  2. 太魔人招新|快来加入我们吧~
  3. ADNI数据集-数据分析11.17
  4. ubyntu 链接mysql_ubuntu下mysql连接(转载)
  5. 优化 Flash 性能
  6. hashCode()和哈希值
  7. 发生了一次 MySQL 误操作导致的事故,「高可用」都顶不住了
  8. python怎么判断等于_python中怎么判断不等于
  9. codec2中的函数命名后缀vb nb sm
  10. 世界上什么人最重要?什么事最重要?什么时间最重要?