zoukankan      html  css  js  c++  java
  • Qt的封装性d指针和q指针

    https://blog.csdn.net/Ghost_bai/article/details/79565373

    d指针

    Qt对于数据的封装算比较高明的了,其实原理就是把接口和实现分开,类似于如下结构:

        class A
        {
            class APrivate;
            APrivate *pData;
            
            public:
            A();
            ~A();
            ...
        }

    这样,接口类A只负责描述希望调用者看到的,而真正的细节都在APrivate类中,当然这是我个人的理解,Qt的实现要复杂的多。
    以QWidget为例

    先看代码:

        QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
            : QObject(*new QWidgetPrivate, 0), QPaintDevice()
        {
            QT_TRY {
                d_func()->init(parent, f);
            } QT_CATCH(...) {
                QWidgetExceptionCleaner::cleanup(this, d_func());
                QT_RETHROW;
            }
        }

    这个是QWidget的构造函数,接着往下看:

        /*!
            internal
        */
        QObject::QObject(QObjectPrivate &dd, QObject *parent)
            : d_ptr(&dd)
        {
            Q_D(QObject);
            d_ptr->q_ptr = this;
            ...
        }

    这个是QObject的构造函数,看到有个d_ptr,类型为QScopedPointer<QObjectData>,现在好像明白了什么,在QWidget的构造函数中new了一个QWidgetPrivate对象,然后保存到基类的d_ptr中。

    这里有两个宏定义,可以获取当前类的d指针,就是Q_D,实现如下:

    #define Q_D(Class) Class##Private * const d = d_func()

    这里有个d_func(),这时什么?不急,在Q_D定义的上方,就有一个Q_DECLARE_PRIVATE定义:

        #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;

    接着就是:

        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(); }

    现在应该明白了,Qt里面细节都放在了Class##Private的类中,也算是一种定好的命名格式。

    Q_DECLARE_PRIVATE这个是在类声明的时候调用Q_DECLARE_PRIVATE(QWidget)。

    只要在使用d指针之前,加上Q_D(QWidget);就可以了。
    q指针

    与d指针相反,q指针是给Class##Private类调用的,是获取接口类的指针,同样有一个Q_Q宏定义:

    #define Q_Q(Class) Class * const q = q_func()

    同样,需要在Class##Private类声明出,调用Q_DECLARE_PUBLIC:

        #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;

    更多细节可还要继续研究。

  • 相关阅读:
    cookie标准话
    thinkphp关联查询
    jq获取表单值与赋值代码
    Github使用.gitignore文件忽略不必要上传的文件 (转)
    python 库 Numpy 中如何求取向量范数 np.linalg.norm(求范数)(向量的第二范数为传统意义上的向量长度),(如何求取向量的单位向量)
    word 使用中 上标符号的实现
    python 编程中的一个关于图片的库 imageio (读取照片RGB内容,转换照片格式)
    交叉熵代价函数(作用及公式推导) ------转载
    cousera 深度学习 吴恩达 第一课 第二周 学习率对优化结果的影响
    python3 读入一个jpg格式的图片,并转换长宽像素个数,然后进行绘制
  • 原文地址:https://www.cnblogs.com/Vancamel/p/11345970.html
Copyright © 2011-2022 走看看