来自Qt源码中有关g指针和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
};
//第二段
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()
这个是pimpl模式,Qt广泛使用。简而言之,就是不让你知道这个类的私有成员是怎样的,有利于信息的隐藏以及高低版本的兼容。
下面给出一个本人的实验:
// 首先模仿QT声明一些宏定义
#ifndef MACRO_H_
#define MACRO_H_
#ifndef DELETE_PTR
#define DELETE_PTR(p){if(p){delete(p);(p)=nullptr;}}
#endif
template <typename T>
static inline T* getPtrHelper(T* ptr)
{
return ptr;
}
#define GX_DECLARE_PRIVATE(Classname) \
inline Classname##Private * d_func() { return reinterpret_cast<Classname##Private *>(getPtrHelper(d_ptr)); } \
inline const Classname##Private * d_func()const { return reinterpret_cast<const Classname##Private *>(getPtrHelper(d_ptr)); } \
friend class Classname##Private;
#define GX_DECLARE_PUBLIC(Classname) \
inline Classname * d_func() { return static_cast<Classname *>(getPtrHelper(g_ptr)); } \
inline const Classname * d_func()const { return static_cast<const Classname *>(getPtrHelper(g_ptr)); } \
friend class Classname;
#define D(Classname) Classname##Private * const d = d_func()
#define G(Classname) Classname * const g = g_func()
#endif
下面的代码是相关的实现:
#ifndef BOSS_H_
#define BOSS_H_
#include <string>
class BossPrivate;
// 声明一个基类
class Boss
{
public:
Boss(BossPrivate* d = nullptr);
virtual ~Boss();
inline BossPrivate* getPrivate(){ return d_ptr; }
protected:
void setPrivate(BossPrivate* bossPrivate);
BossPrivate* d_ptr; // d_ptr很重要
};
class BossPrivate
{
public:
BossPrivate();
BossPrivate(const BossPrivate& bp);
virtual ~BossPrivate();
Boss* g_ptr; // g_ptr很重要
};
#endif
#include "Boss.h"
#include "Macro.h"
Boss::Boss(BossPrivate* d) : d_ptr(d)
{
if (!d_ptr)
{
d_ptr = new BossPrivate;
}
setPrivate(d_ptr);
}
Boss::~Boss()
{
DELETE_PTR(d_ptr);
}
void Boss::setPrivate(BossPrivate* bossPrivate)
{
if (!bossPrivate || bossPrivate == d_ptr)
return;
DELETE_PTR(d_ptr);
d_ptr = bossPrivate;
d_ptr->g_ptr = this;
}
BossPrivate::BossPrivate() :g_ptr(nullptr)
{
}
BossPrivate::BossPrivate(const BossPrivate& bp)
{
if (this != &bp)
g_ptr = bp.g_ptr;
}
BossPrivate::~BossPrivate()
{
DELETE_PTR(g_ptr);
}
基于基类的子类的实现:
#include "Macro.h"
#include "Boss.h"
class SalaryPrivate;
class Salary : public Boss
{
public:
Salary(double x1, double x2, double x3);
~Salary();
double calTrueSalary();
private:
GX_DECLARE_PRIVATE(Salary); // 数据成员完全隐藏,
};
// 数据隐藏后的实现,
#include "CalSalary.h"
class SalaryPrivate : BossPrivate
{
GX_DECLARE_PUBLIC(Salary);
public:
SalaryPrivate(double x1, double x2, double x3)
{
_salary = new Salary(x1, x2, x3);
_sum = x1 + x2 + x3;
}
private:
Salary* _salary;
double _sum;
};
Salary::Salary(double x1, double x2, double x3) : Boss(new SalaryPrivate(x1,x2,x3))
{
}
Salary::~Salary()
{
D(Salary);
DELETE_PTR(d->_salary);
}
double Salary::calTrueSalary()
{
D(Salary);
return d->_sum;
}