inside qt series (四):对象数据存储(c)-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 38684
  • 博文数量: 30
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2020-10-13 16:47
文章分类

(30)

  • (7)
  • (23)
  • (0)
文章存档

(30)

我的朋友
最近访客
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: linux

2020-10-13 16:53:05

原文地址: 作者:

作者:q-kevin @

接上节,让我们来看看这个 qobjectprivate 和 qobject 是如何关联在一起的。

//————————————————————————————————————–
// file name: qobject.cpp

qobject::qobject(qobject *parent)
    : d_ptr(new qobjectprivate)
{
  // ………………………
}

qobject::qobject(qobjectprivate &dd, qobject *parent)
    : d_ptr(&dd)
{
   // …………………
}

怎么样,是不是一目了然呀?

从第一个构造函数可以很清楚的看出来,qobject class 中的 d_ptr 指针将指向一个 qobjectprivate 的对象,而qobjectprivate这个class是从qobjectdata继承出来的。

这第二个构造函数干什么用的呢?从 qobject class 的定义中,我们可以看到,这第二个构造函数是被定义为 protected 类型的,这说明,这个构造函数只能被继承的class使用,而不能使用这个构造函数来直接构造一个qobject对象,也就是说,如果写一条下面的语句, 编译的时候是会失败的,
        new qobject(*new qobjectprivate, null)

为了看的更清楚,我们以qwidget这个class为例说明

qwidget是qt中所有ui控件的基类,它直接从qobject继承而来,

class qwidget : public qobject, public qpaintdevice
{
    q_object
    q_declare_private(qwidget)
    // …………………
}

我们看一个这个class的构造函数的代码:
qwidget::qwidget(qwidget *parent, qt::windowflags f)
    : qobject(*new qwidgetprivate, 0), qpaintdevice()
{
    d_func()->init(parent, f);
}

非常清楚,它调用了基类qobject的保护类型的构造函数,并且以 *new qwidgetprivate 作为第一个参数传递进去。也就是说,基类(qobject)中的d_ptr指针将会指向一个qwidgetprivate类型的对象。

再看qwidgetprivate这个class的定义:

class qwidgetprivate : public qobjectprivate
{
    q_declare_public(qwidget)
    // …………………
}

好了,这就把所有的事情都串联起来了。

关于qwidget构造函数中的唯一的语句 d_func()->init(parent, f) 我们注意到在class的定义中有这么一句话: q_declare_private(qwidget)

我们前面讲过这个宏,当把这个宏展开之后,就是这样的:

inline qwidgetprivate* d_func() { return reinterpret_cast(d_ptr); }
inline const qwidgetprivate* d_func() const
{ return reinterpret_cast(d_ptr); } \
friend class qwidgetprivate;

很清楚,它就是把qobject中定义的d_ptr指针转换为qwidgetprivate类型的指针。

小结:

要理解qt kernel的code,就必须要知道qt中每一个object内部的数据是如何保存的,而qt没有象我们平时写code一样,把所有的变量直接定义在类 中,所以,不搞清楚这个问题,我们就无法理解一个相应的class。其实,在qt4.6中的类成员数据的保存方法在本质是与qt2.x中的是一样的,就是 在class中定义一个成员数据的指针,指向成员数据集合对象(这里是一个qobjectdata或者是其派生类)。初始化这个成员变量的办法是定义一个 保护类型的构造函数,然后在派生类的构造函数new 一个派生类的数据成员,并将这个新对象赋值给qobject的数据指针。在使用的时候,通过预先定义个宏里面的一个inline函数来把数据指针在安全类 型转换,就可以使用了。
 

======================================================================
声明:
《inside qt series》专栏文章是()原创技术文章。
本系列专栏文章可随意转载,但必须保留本段声明和每一篇文章的原始地址。
作者保留凯发k8官网下载客户端中心的版权,未经作者同意,不得用于任何商业用途

《inside qt series》专栏文章总索引:
本文原始地址:

阅读(1226) | 评论(0) | 转发(0) |
0

上一篇:

下一篇:

给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图