Qt中的C++指针
q_ptr:在私有类中定义一个名字为q_ptr,类型为公有类的数据指针,通过这个指针来访问公有类的数据。
d_ptr:在公有类中定义一个名字为d_ptr,类型为私有类的数据指针,通过这个指针来访问私有类的数据。
具体定义在qglobal.h文件中:
// The body must be a statement:
#define Q_CAST_IGNORE_ALIGN(body) QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wcast-align") body QT_WARNING_POP
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() noexcept \
{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
inline const Class##Private* d_func() const noexcept \
{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
friend class Class##Private;
#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
inline Class##Private* d_func() noexcept \
{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr));) } \
inline const Class##Private* d_func() const noexcept \
{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr));) } \
friend class Class##Private;
#define Q_DECLARE_PUBLIC(Class) \
inline Class* q_func() noexcept { return static_cast<Class *>(q_ptr); } \
inline const Class* q_func() const noexcept { return static_cast<const Class *>(q_ptr); } \
friend class Class;
#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()
d_ptr和q_ptr不是随意取的名字,而是在qglobal中定义好的。
在公有类中使用Q_D(公有类的类名),就可以通过d->XXX的形式区访问私有类的成员变量。
因为在源码中
#define Q_D(Class) Class##Private * const d = d_func()
传入的类名会自动拼接成 “类名Private”,##是宏定义的连字符 。使用d来接受d_func()函数返回的指针。
举个栗子
class Aprivate
{
Q_DECLARE_PUBLIC(A)
public:
int a;
QString b
private:
A *q_ptr;
}
class A
{
public:
void getvalue();
private:
const QpScopePointer<Aprivate> d_ptr;
};
int A::geta()
{
Q_D(A);
return d->a;
}