自学内容网 自学内容网

QT的d指针和p指针

在 Qt 中,d 指针和 p 指针是 PIMPL(Pointer to Implementation)设计模式的具体实现。它们用于将类的实现细节隐藏在一个单独的类中,从而提高封装性、减少编译依赖,并改善二进制兼容性。


1. d 指针(d-pointer)

d 指针是 Qt 中用于指向私有实现类(Private Implementation Class)的指针。它的命名约定是 d_ptr

作用

  • 将类的实现细节隐藏在私有类中。

  • 公有类只暴露接口,不包含任何私有成员或方法的实现。

  • 减少头文件的依赖,加快编译速度。

实现方式

  1. 在公有类中定义一个指向私有类的指针(通常是 QScopedPointer 或 std::unique_ptr)。

  2. 私有类的名称通常是 ClassNamePrivate

示例

// myclass.h
#include <QObject>

class MyClassPrivate; // 前向声明私有类

class MyClass : public QObject {
    Q_OBJECT
public:
    MyClass(QObject *parent = nullptr);
    ~MyClass();

    void publicMethod();

private:
    Q_DECLARE_PRIVATE(MyClass) // 声明 d 指针
    QScopedPointer<MyClassPrivate> d_ptr; // 定义 d 指针
};

// myclass.cpp
#include "myclass.h"

// 私有类的定义
class MyClassPrivate {
public:
    void privateMethod() {
        // 私有方法的实现
    }

    int privateData = 42; // 私有成员变量
};

// 公有类的构造函数
MyClass::MyClass(QObject *parent)
    : QObject(parent), d_ptr(new MyClassPrivate) {}

// 公有类的析构函数
MyClass::~MyClass() {}

// 公有方法的实现
void MyClass::publicMethod() {
    Q_D(MyClass); // 展开为 MyClassPrivate *d = d_func();
    d->privateMethod(); // 访问私有方法
    int value = d->privateData; // 访问私有成员
}

2. p 指针(p-pointer)

p 指针是 Qt 中用于指向父类(Parent Class)的指针。它的命名约定是 q_ptr

作用

  • 在私有类中访问公有类的成员。

  • 通常与 d 指针配合使用,形成双向访问。

实现方式

  1. 在私有类中定义一个指向公有类的指针(通常是 QPointer 或裸指针)。

  2. 在公有类的构造函数中,将 this 指针传递给私有类。

示例

// myclass.h
#include <QObject>

class MyClassPrivate; // 前向声明私有类

class MyClass : public QObject {
    Q_OBJECT
public:
    MyClass(QObject *parent = nullptr);
    ~MyClass();

    void publicMethod();

private:
    Q_DECLARE_PRIVATE(MyClass) // 声明 d 指针
    QScopedPointer<MyClassPrivate> d_ptr; // 定义 d 指针
};

// myclass.cpp
#include "myclass.h"

// 私有类的定义
class MyClassPrivate {
public:
    MyClassPrivate(MyClass *parent)
        : q_ptr(parent) {}

    void privateMethod() {
        // 访问公有类的成员
        Q_Q(MyClass); // 展开为 MyClass *q = q_func();
        q->publicMethod();
    }

    int privateData = 42; // 私有成员变量

private:
    MyClass *const q_ptr; // 定义 p 指针
    Q_DECLARE_PUBLIC(MyClass) // 声明 p 指针
};

// 公有类的构造函数
MyClass::MyClass(QObject *parent)
    : QObject(parent), d_ptr(new MyClassPrivate(this)) {}

// 公有类的析构函数
MyClass::~MyClass() {}

// 公有方法的实现
void MyClass::publicMethod() {
    Q_D(MyClass); // 展开为 MyClassPrivate *d = d_func();
    d->privateMethod(); // 访问私有方法
    int value = d->privateData; // 访问私有成员
}

3. Q_D 和 Q_Q 宏

为了简化 d 指针和 p 指针的使用,Qt 提供了以下宏:

  • Q_D(Class):在公有类中获取 d 指针。

    Q_D(MyClass); // 展开为 MyClassPrivate *d = d_func();

  • Q_Q(Class):在私有类中获取 p 指针。

    Q_Q(MyClass); // 展开为 MyClass *q = q_func();


4. 总结

  • d 指针:指向私有实现类的指针,用于隐藏实现细节。

  • p 指针:指向公有类的指针,用于在私有类中访问公有类的成员。

  • Q_DECLARE_PRIVATE 和 Q_DECLARE_PUBLIC:用于声明 d 指针和 p 指针。

  • Q_D 和 Q_Q 宏:用于简化 d 指针和 p 指针的访问。

通过使用 d 指针和 p 指针,Qt 实现了良好的封装性和二进制兼容性,同时减少了编译依赖。


原文地址:https://blog.csdn.net/Alon1787/article/details/145282463

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!