10

考虑以下 Qt 类:

#include <QScopedPointer>

class MyClassPrivate;
class MyClass
{
    public:
        MyClass();
        ~MyClass();
    private:
        QScopedPointer<MyClassPrivate> d_ptr;
        Q_DECLARE_PRIVATE(MyClass)
}

此类类似于大多数实现私有实现的 Qt 类的结构。该宏Q_DECLARE_PRIVATE将导致以下扩展(从 Qt5 开始):

inline MyClassPrivate* d_func()
    { return reinterpret_cast<MyClassPrivate *>(qGetPtrHelper(d_ptr)); }
inline const MyClassPrivate* d_func() const
    { return reinterpret_cast<const MyClassPrivate *>(qGetPtrHelper(d_ptr)); }
friend class MyClassPrivate;

这令人困惑——为什么不d_ptr直接在成员函数中使用?换句话说,而不是这样做:

Q_D(MyClass);
d->member = 12345;

为什么不这样做?

d_ptr->member = 12345;

有一个显式函数(基本上)只返回d_ptr并在堆栈上产生额外变量的开销的原因是什么?

4

1 回答 1

9

如果派生类和基类各有一个Private结构,会浪费更多的内存,因此在Qt中,私有类也是继承的,派生类和基类共享一个d_ptr。这样做的问题是 d_ptr 现在是 BasePrivate 类型。

class Base
{
protected:
    BasePrivate * d_ptr;
}

class Derived
{
// There is not d_ptr declared
}

所以你可以看到,在派生类中,当它访问 d_ptr 时,类型是 BasePrivate*。所以它需要将 d_ptr 转换为 DerivedPrivate*。d_func 函数是内联的,一旦编译,它总是将 d_ptr 转换为正确的类型。

这篇文章比我在这里说的更好,我建议你阅读它。

于 2013-04-10T03:06:06.673 回答