Consider the following Qt class:
#include <QScopedPointer>
class MyClassPrivate;
class MyClass
{
public:
MyClass();
~MyClass();
private:
QScopedPointer<MyClassPrivate> d_ptr;
Q_DECLARE_PRIVATE(MyClass)
}
This class resembles the structure of most Qt classes that implement private implementation. The macro Q_DECLARE_PRIVATE
will cause the following expansion (as of 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;
This is confusing - why isn't d_ptr
used directly in member functions? In other words, instead of doing this:
Q_D(MyClass);
d->member = 12345;
Why not do this?
d_ptr->member = 12345;
What is the reason for having an explicit function that (basically) just returns the d_ptr
and incurs the overhead of an extra variable on the stack?
If the derived class and base class each has a Private structure, it would waste more memory, thus in Qt, the private class is also inherited, and the derived class and the base class shares one d_ptr. The problem of doing so is that the d_ptr is now of type BasePrivate.
class Base
{
protected:
BasePrivate * d_ptr;
}
class Derived
{
// There is not d_ptr declared
}
So you can see, in the derived class, when it access d_ptr, the type is BasePrivate*. So it needs to cast d_ptr to DerivedPrivate*. The d_func function is inline, once compiled, it will always cast the d_ptr to the correct type.
This post illustrates better than what I say here, I suggest you read it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With