使用Q_D指针指向私有成员和Q_Q指针指向公开成员
开发DLL为什么要使用Q_D/Q_Q指针?
假如,我们要把下面这个类封装成DLL:
class MyClass
{
public:
MyClass();
~MyClass();
private:
int myVar;
};
显然,这个私有成员myVar是我们不想给第三方看到的,而且是代码二进制兼容性的大敌。所以我们使用Q_D指针和Q_D指针,对该私有成员myVar进行私有化。
1、使用d_ptr指针指向MyClass的私有成员
我们定义一个私有类MyClassPrivate,并配合Q_DECLARE_PRIVATE宏,以定义指针d_ptr指向该私有类。
class MyClassPrivate;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassPrivate * const d_ptr;
Q_DECLARE_PRIVATE(MyClass);
};
然后,我们把MyClass类中该隐藏的变量塞到私有类MyClassPrivate中,下面展示私有类MyClassPrivate的实现:
class MyClassPrivate
{
public:
MyClassPrivate(MyClass *parent);
private:
MyClass * const q_ptr;
Q_DECLARE_PUBLIC(MyClass);
int myVar;
};
2、使用q_ptr指针指向MyClass的公有成员
从私有类MyClassPrivate的实现代码可以看到,我们在私有类中,配合Q_DECLARE_PUBLIC宏来定义q_ptr指针指向MyClass的公有成员。
以上就是Qt使用Q_D和Q_Q指针私有实现的基本方法,下面给出一个比较完整的例子:
[ myclass.h]
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QtCore/QObject>
class MyClassPrivate;
class MyClass: public QObject
{
Q_OBJECT
public:
MyClass(QObject *parent = 0);
virtual ~MyClass();
void dummyFunc();
signal:
void dummySignal();
private:
MyClassPrivate * const d_ptr = nullptr;
Q_DECLARE_PRIVATE(MyClass);
Q_DISABLE_COPY(MyClass);//防止指针d_ptr的二次释放
};
#endif // MYCLASS_H
[myclass.cpp]
#include "myclass.h"
class MyClassPrivate : public QObject
{
public:
MyClassPrivate(MyClass *parent)
: q_ptr(parent)
{
}
void foobar()
{
Q_Q(MyClass);
emit q->dummySignal();
}
private:
MyClass * const q_ptr;
Q_DECLARE_PUBLIC(MyClass);
};
MyClass::MyClass(QObject *parent)
: QObject(parent)
, d_ptr(new MyClassPrivate(this))
{
}
MyClass::~MyClass()
{
Q_D(MyClass);
delete d;
}
void MyClass::dummyFunc()
{
Q_D(MyClass);
d->foobar();
}