Inside Qt Series (四):對象資料存放區(C)

來源:互聯網
上載者:User

接上節,讓我們來看看這個 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<QWidgetPrivate *>(d_ptr); }
inline const QWidgetPrivate* d_func() const
{ return reinterpret_cast<const QWidgetPrivate *>(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》專欄文章是(http://www.qkevin.com)原創技術文章。
本系列專欄文章可隨意轉載,但必須保留本段聲明和每一篇文章的原始地址。
作者保留著作權,未經作者同意,不得用於任何商業用途

《Inside Qt Series》專欄文章總索引: http://www.qkevin.com/qt
本文原始地址:http://www.qkevin.com/archives/63

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.