考虑以下Qt类:
#include <QScopedPointer>
class MyClassPrivate;
class MyClass
{
public:
MyClass();
~MyClass();
private:
QScopedPointer<MyClassPrivate> d_ptr;
Q_DECLARE_PRIVATE(MyClass)
}
Run Code Online (Sandbox Code Playgroud)
此类类似于实现私有实现的大多数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;
Run Code Online (Sandbox Code Playgroud)
这很令人困惑 - 为什么不d_ptr直接在成员函数中使用?换句话说,而不是这样做:
Q_D(MyClass);
d->member = 12345;
Run Code Online (Sandbox Code Playgroud)
为什么不这样做?
d_ptr->member = 12345;
Run Code Online (Sandbox Code Playgroud)
具有显式函数的原因是什么(基本上)只是返回d_ptr并导致堆栈上额外变量的开销?
如果派生类和基类都具有Private结构,则会浪费更多内存,因此在Qt中,私有类也是继承的,派生类和基类共享一个d_ptr.这样做的问题是d_ptr现在是BasePrivate类型.
class Base
{
protected:
BasePrivate * d_ptr;
}
class Derived
{
// There is not d_ptr declared
}
Run Code Online (Sandbox Code Playgroud)
所以你可以在派生类中看到,当它访问d_ptr时,类型是BasePrivate*.所以它需要将d_ptr强制转换为DerivedPrivate*.d_func函数是内联的,一旦编译,它将始终将d_ptr强制转换为正确的类型.
这篇文章比我在这里说的更好,我建议你阅读它.