2015-01-21 36 views
1

在C++ Qt中,我喜歡用QSharedPointers來管理我的堆內存,但是可以/還是應該使用它們來管理QAbstractItemModel中的數據?在QSharedPointers中管理QAbstractItemModel數據

例如,可以有一個QStrings QList<QSharedPointer<QString> > queue的列表。

問題是,當執行QSharedAbstractItemModel,如QAbstractListModel時,您需要處理原始指針。例如,方法index返回一個QModelIndex,它在構造函數中接受一個void指針,指向堆上的那些QStrings中的一個。只要你創建了這個對象,你就可以使用託管和非託管的堆內存。

因此,如果我將指定的項存儲在某個指針的某個位置,然後清除我的模型,那麼該指針的數據將被刪除。

那麼,如何處理要放在一個QAbstractItemModel

堆內存中的對象我使用QT 5.1。

+0

Halfgaar,這並不回答你的問題,但爲什麼不只是'QList '? Qt使用[隱式共享](http://doc.qt.io/qt-5/implicit-sharing.html),所以它會負責爲您共享數據 – 2015-01-21 14:45:23

+0

我知道隱式共享。這是因爲我處理自己的對象列表,我需要保留信號和插槽連接。 – Halfgaar 2015-01-21 16:39:56

回答

2

在內存管理方面,這取決於您的選擇。

QAbstractListModel需要您編寫返回QVariant的數據函數。你從哪裏創建變體並不重要。

的的QVariant本身是一個新的結構,它沒有任何影響您的數據。

拿這個例子:

QVariant MyListImplementation::data(const QModelIndex& index, int role) const 
{ 
    // QSharedPointer<QList<QString>> sharedMessageQueue 
    // QList<QString>* pMessageQueue 
    if (useSharedPointers) 
    { 
     return QVariant::fromValue(sharedMessageQueue->at(index.row())); 
    } else { 
     return QVariant::fromValue(pMessageQueue->at(index.row)); 
    } 
} 

所以你可以看到兩件事情:

  1. 你從價值創造的QVariant,你是按值傳遞這個的QVariant,這意味着的QVariant有他自己的記憶,和內存管理被傳遞到請求數據對象(你不能返回的QVariant的共享指針,因爲你需要實現這個特定方法簽名)

  2. 實現是獨立於你正在使用你的「的MessageQueue」列表中的內存政策

如果使用共享的指針清單中的數據,您將不必在擔心列表的重新分配析構函數,如果你不需要刪除類的析構函數中的列表。

如果您想討論一下在QAbstarctListModel實現中使用QSharedPointers是否合適,您將得到與問題「在項目中使用共享指針時是否有用並且有什麼折衷?」相同的答案。 。

編輯:

關於你的評論:

你所擔心的createIndex時,被用於生成QModelIndex和使用QModelIndex內部原始的指針會發生什麼。

在Qt文檔:

注:型號指標應立即使用,然後丟棄。在調用改變模型結構或刪除項目的模型函數之後,您不應該依賴索引來保持有效。如果您需要隨時間保持模型索引,請使用QPersistentModelIndex。

...

QModelIndex化QAbstractItemModel的createIndex ::(INT行,INT列,無效* PTR = 0)const的[保護]

創建給定行和列與內部模型索引指針ptr。

當使用QSortFilterProxyModel時,其索引具有自己的內部指針。在模型之外訪問這個內部指針是不可取的。改用data()函數。

我的理解是,QModelIndex只是用於檢索模型數據的臨時結構。在使用數據庫時,將其視爲臨時表的等價物:您知道您將從某個表(並非所有信息)訪問程序的某個部分中的多個操作的某些信息,但您不想查詢每個數據庫的數據庫,你只需將它們作爲一個查詢的批量使用,根據需要使用它們,然後丟棄。

QT文檔提到了一個實際的例子,其中QModelIndex可用於訪問模型外的數據(因此不是使用model.data,而是使用QModelIndex.data),但這是一個例外,因爲雖然數據存在於內存中按照相同的順序輸入,它們的索引被改變(因爲排序/過濾)。

在內存管理方面,QModelIndex在其內部保留弱指針,因此,如果刪除數據,QModelIndex將指向無效位置。但是在丟棄內存方面,你不必擔心,因爲它不會分配任何東西(弱指針:))。

如果您需要擔心的確實是在多線程環境中,您在線程A中獲得QModelIndex,但在線程A放棄此QModelIndex之前,線程B會刪除模型。但是,如果你有這個問題,你有一個同步問題。

您可以通過創建QModelIndex的深層副本(意味着您將複製它的內部指針,然後將其作爲共享指針)來繞過此整個同步,但如果可能的話,我會同步。

+0

我的問題更多的是在'QList >隊列'vs'QList 隊列'中。數據方法不是問題。我更擔心從'queue.at'創建'QModelIndex',然後傳遞一個原始指針。 – Halfgaar 2015-01-21 10:48:08