在研究QCoreApplication类的代码时,无意间弄明白了“d_func()”和“d指针”的来源:

class Q_CORE_EXPORT QCoreApplication
#ifndef QT_NO_QOBJECT
: public QObject
#endif
{
……
Q_DECLARE_PRIVATE(QCoreApplication)
public:
……
~QCoreApplication();
……
protected:
QCoreApplication(QCoreApplicationPrivate &p);

#ifdef QT_NO_QOBJECT
QScopedPointer<QCoreApplicationPrivate> d_ptr;
#endif
};
上面的代码中出现了一个红“Q_DECLARE_PRIVATE”,接下来看看这个宏的作用。

template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
template <typename Wrapper> static inline typename Wrapper::pointer\
qGetPtrHelper(const Wrapper &p) { return p.data(); }
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
friend class Class##Private;
发现这个展开后引入了d_func()这个函数。但是“d指针”和这个宏又有什么关系呢?那就要说到另一个宏“Q_D”看如下的代码

#define Q_D(Class) Class##Private * const d = d_func()
从代码中可知,d_func()和d指针是紧密联系的。在Qt源码中“d_func()函数”和“d指针”的使用无处不在!
在接下的过程中又发现了另一组宏“Q_DECLARE_PUBLIC、Q_Q”,代码如下:

#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;

#define Q_Q(Class) Class * const q = q_func()
这组宏引入了“q_func()函数”和“q指针”,这两个在Qt代码中遇见较少,留待以后研究。

http://qtdream.com/topic/257/qt%E4%B8%AD%E6%97%A0%E5%A4%84%E4%B8%8D%E5%9C%A8%E7%9A%84d%E6%8C%87%E9%92%88%E4%B8%BA%E4%BD%95%E6%96%B9%E7%A5%9E%E5%9C%A3/4

-------------------------------------------------------------------------------

这个是pimpl模式,Qt广泛使用。简而言之,就是不让你知道这个类的私有成员是怎样的,有利于信息的隐藏以及高低版本的兼容。

可以看看这两篇博文
http://blog.csdn.net/mznewfacer/article/details/6976293
http://blog.csdn.net/zhu_xz/article/details/6035861

Qt中无处不在的d指针为何方神圣的更多相关文章

  1. QT 中使用 c++ 的指针

    之前没有接触过 c++,不过听说 c++ 的指针很坑,直到最近在用 QT / C++ 写一个 Linux Deepin 系统上检测网络流量和网速的小程序时,发现 c++ 的指针用起来真的特别蛋疼. 不 ...

  2. Qt中窗口退出事件

    窗口右上角的X按键会导致其在不给出任何提示的情况下直接退出, 当点击右上角的x按键时,会触发Qt中的一个事件处理函数:void QWidget::closeEvent ( QCloseEvent * ...

  3. Qt中的ui指针和this指针

    初学qt,对其ui指针和this指针产生疑问,画了个把小时终于搞懂了. 首先看ui指针的定义: 在mainwindow.h中 private: Ui::MainWindow *ui; Ui又是什么? ...

  4. Qt中的Q_D宏和d指针

    _ZTS7QObject 一.Q_D的在文件中的提法 Q_D的设置意在方便地获取私有类指针,文件为qglobal.h.下面的##是宏定义的连字符.假设类名是A,那么A##Private翻译过来就是AP ...

  5. 智能指针类模板(中)——Qt中的智能指针

    Qt中的智能指针-QPointer .当其指向的对象被销毁时,它会被自动置空 .析构时不会自动销毁所指向的对象-QSharedPointer .引用计数型智能指针 .可以被自由的拷贝和赋值 .当引用计 ...

  6. PyQt(Python+Qt)学习随笔:Qt中的部分类型QString、QList和指针、引用在PyQt中的实现方式

    老猿Python博文目录 老猿Python博客地址 在我们查阅Qt的文档资料时,可以看到Qt中的链表使用的是QList,字符串使用的是QString,但老猿在测试时发现这两个类型PyQt不支持,无法找 ...

  7. Qt 中使用Singleton模式需小心

    在qt中,使用Singleton模式时一定要小心.因为Singleton模式中使用的是静态对象,静态对象是直到程序结束才被释放的,然而,一旦把该静态对象纳入了Qt的父子对象体系,就会导致不明确的行为. ...

  8. qt中ui的 使用介绍

    1.什么是ui?ui通常是用Qt 设计师设计出来的界面文件的后缀.通常情况下ui是一个指向这个界面类的指针.ui-> 一般就是用来访问这个界面类里面的控件.例如你的ui文件里有一个叫okButt ...

  9. Qt中sizeof

    class a{ int d; // virtual void ssss(); }; qDebug() <<sizeof(a) << sizeof(int) << ...

随机推荐

  1. nodejs安装不了和npm安装不了的解决方法

    http://caibaojian.com/nodejs-roll-back.html

  2. qingshow “不积跬步无以至千里,不积小流无以成江海”。--荀子《劝学篇》 用tomcat+花生壳搭建自己的web服务器+域名(参考)

    链接地址:http://www.blogjava.net/qingshow/archive/2010/01/17/309846.html 用tomcat搭建web服务器 目标:免费拥有自己的网站及域名 ...

  3. Server-side Sessions with Redis | Flask (A Python Microframework)

    Server-side Sessions with Redis | Flask (A Python Microframework) Server-side Sessions with Redis By ...

  4. Sting和StringBuffer的区别

    java.lang.String代表不可变序列: s1 = "hello"; s2 = "world"; s1 = s1 + s2; 内存分配情况是s1有块内存 ...

  5. document.documentElement 和document.body 以及其属性

    js中document.documentElement 和document.body 以及其属性 (原来HTML里是document.body  --XHTML里是document.documentE ...

  6. mysql双机热备的配置步骤

    设置双机热备: 首先要在两台机器上建立同步用户: grant replication slave on *.* to 'repdcs'@'192.168.21.39' identified by '1 ...

  7. ioctl、文件操作接口函数以及nand的升级模式的操作过程详解

    概述 内核中驱动文件的操作通常是通过write和read函数进行的,但是很多时候再用户空间进行的操作或许不是内核中公共代码部分提供的功能,此时就需要使用一种个性化的方法进行操作--ioctl系统调用. ...

  8. gdb 远程qemu-arm调试

    把 c 编译成 arm 指令的可运行文件 /usr/bin/arm-linux-gnueabi-g++ hello.cpp cat hello.cpp #include <stdio.h> ...

  9. zoj 1134 - Strategic Game

    题目:给你一棵树.找到最小的顶点集合,使得全部的边至少有一个顶点在这个集合中. 分析:树形dp,图论,最小顶点覆盖. 方案1:树形dp.分别记录每一个节点取和不取的最优解f(k.0)与f(k,1): ...

  10. 恢复PasswordChar 默认值、取消密码框设置

    //三种都是清空 this.textBox1.PasswordChar = new char(); this.textBox1.PasswordChar = '\0'; this.textBox1.P ...