Next, let's take a look at how this qobjectprivate and Qobject are linked together.
//File Name:qobject.cpp
Qobject::qobject (Qobject *parent)
: D_ptr (New Qobjectprivate)
{
...........................
}
Qobject::qobject (qobjectprivate &dd, Qobject *parent)
: D_ptr (&DD)
{
.....................
}
How, is not at a glance AH.
From the first constructor it is clear that the d_ptr pointer in the Qobject class will point to a Qobjectprivate object, and Qobjectprivate this class is inherited from Qobjectdata.
What is this second constructor for? From the definition of Qobject class, we can see that this second constructor is defined as the protected type, which means that the constructor can only be used by the inherited class, and cannot use this constructor to construct a Qobject object directly, that is to say, If you write one of the following statements, the compilation will fail,
New Qobject (*new qobjectprivate, NULL)
To see more clearly, we use the class of qwidget as an example to illustrate.
Qwidget is the base class for all UI controls in Qt, and it inherits directly from Qobject.
Class Qwidget:public Qobject, public qpaintdevice
{
Q_object
Q_declare_private (Qwidget)
// .....................
}
Let's look at a code for this class's constructor:
Qwidget::qwidget (Qwidget *parent, Qt::windowflags f)
: Qobject (*new qwidgetprivate, 0), Qpaintdevice ()
{
D_func ()->init (parent, f);
}
It is very clear that it invokes the constructor for the protection type of the base class Qobject and is passed in as the first parameter with *new qwidgetprivate. In other words, the d_ptr pointer in the base class (Qobject) will point to an object of type Qwidgetprivate.
And look at the definition of the class Qwidgetprivate:
Class Qwidgetprivate:public Qobjectprivate
{
Q_declare_public (Qwidget)
// .....................
}
Well, it's all connected.
About the only statement in the Qwidget constructor D_func ()->init (parent, F) We note that there is a sentence in the definition of class: Q_declare_private (Qwidget)
We've talked about this macro before, and when this macro is expanded, it's like this:
Inline qwidgetprivate* D_func () {return reinterpret_cast<qwidgetprivate *> (d_ptr);}
Inline const qwidgetprivate* D_func () const
{return reinterpret_cast<const qwidgetprivate *> (d_ptr);} /
Friend class Qwidgetprivate;
It is clear that it is converting the d_ptr pointer defined in Qobject to a pointer of type qwidgetprivate.
Summary:
To understand the code of QT kernel, it is necessary to know how the data inside each of the objects within Qt is stored, and QT does not have all the variables defined directly in the class as we normally write code, so we cannot understand a corresponding class without knowing the problem. In fact, the method of preserving class member data in QT4.4 is essentially the same as in qt2.x, which is to define a pointer to a member's data in class, pointing to the member data collection object (here is a qobjectdata or its derived class). The way to initialize this member variable is to define a constructor for the type of protection, and then in the constructor of the derived class new a data member of the derived class and assign the new object to the Qobject data pointer. When used, the data pointer is converted to a security type by pre-defining an inline function in the macro, which can be used.
====================================
Statement:
The Inside QT Series column is the original technical article of the QT Core Technology Forum (insideqt.com).
This series of columns may be reproduced at will, but this paragraph and the original address of each article must be retained.
Not for commercial use without the consent of the author
"Inside Qt Series" Column Total index:
Http://www.insideqt.com/bbs/viewthread.php?tid=9&extra=page%3D1
Original address of this article:
Http://www.insideqt.com/bbs/viewthread.php?tid=7&extra=page%3D1
====================================