在研究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. NGUI 3.5教程(二)Label 标签 (Hello world)、多行文本

    写在前面:     本文将创建NGUI的第一个样例.依照编程传统,第一个样例,就是做一个Hello world 显示出来.NGUI.我们用Label来实现 . 欢迎大家纠错.拍砖!原创非常辛苦,如有转 ...

  2. poj1573&amp;&amp;hdu1035 Robot Motion(模拟)

    转载请注明出处:http://blog.csdn.net/u012860063? viewmode=contents 题目链接: HDU:pid=1035">http://acm.hd ...

  3. C#面向对象2 静态类、静态成员的理解

    理解:静态成员属于类所有,为各个类的实例所公用,与实例无关,需要全局共享的属性或者方法定义成静态的 C#静态成员:  1.静态成员属于类所有,故用类名调用,非静态成员属于类的实例所有,用实例名调用  ...

  4. jquery-easyui界面皮肤设计

    发现easy-ui 没有皮肤切换功能 正好工作要用就做了个 分享给大家 暂时做了绿色.橘黄.灰黑.蓝色.红色这5种颜色,大家也可以参照的多做几套更漂亮一点的! demo.rar (932.1 KB)

  5. 利用VS2005进行dump文件调试(17篇博客)

    前言:利用drwtsn32或NTSD进行程序崩溃处理,都可以生成可用于调试的dmp格式文件.使用VS2005打开生成的DMP文件,能很方便的找出BUG所在位置.本文将讨论以下内容: 1.  程序编译选 ...

  6. QT在构造函数中退出程序

    原地址:http://www.tuicool.com/articles/RZnYze 在QT的界面类的构造过程中,如果想退出整个程序,暴力的做法是调用exit(-1)进行,另外一种不是那么暴力的方式如 ...

  7. 8天玩转并行开发——第二天 Task的使用

    原文 8天玩转并行开发——第二天 Task的使用 在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于 “任务的编程模型”所冲击, ...

  8. 基于visual Studio2013解决C语言竞赛题之1088模拟计算器

        题目 解决代码及点评 /************************************************************************/ /* ...

  9. 在O(1)时间删除指定链表结点

    #region 在O(1)时间删除指定链表结点 /// <summary> /// 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. /// </summa ...

  10. oracle至mysql该指南的数据模式()任意数据源之间的跨导应用

    为了产生的一些资源的库的释放.需要API模块迁移到mysql在,需要引导数据. 试用oracle to mysql工具.当迁移错误不说,如此大量的数据的,有了这样简陋的工具是不太可靠. 意外的发现工具 ...