簡體   English   中英

我應該如何在Qt中存儲指針?

[英]How should I store pointers in Qt?

我的寵物項目已經到了我應該開始跟蹤指針生命周期的程度,我正在嘗試為它開發一些系統。 遺憾的是,由於Qt API本身在每個場合都使用裸指針,所以在各地都使用智能指針的流行建議並不適用。 所以,我想出的是:

  1. 對於Qt所擁有的一切,

    • 在本地使用指針;
    • 在功能之間傳遞它們;
    • 將它們存儲為子類化的QPointer ,在轉換為naked之前進行isNull()檢查。
  2. 對於我所擁有的一切,請按照建議使用智能指針。 我將在這里使用std::版本。

  3. 困擾我的案例。 對於切換所有權的對象(例如從布局添加/刪除的小部件)

    • 使用,儲存,指揮裸體;
    • 適當時手動delete它們。

建議,意見,建議? 我自己並不喜歡這個計划。

首先,盡可能按價值保存。 查看newmake_uniquemake_shared每個用法 - 您必須證明每個動態對象的創建是正確的。 如果子對象具有與父對象相同的生命周期,則按值保持是一個明智的選擇。 例如:

class MyWidget : public QWidget {
  Q_OBJECT
  QGridLayout m_topLayout{this};
  QLabel m_sign{"Hello World"};
public:
  MyWidget(QWidget * parent = nullptr) : QWidget{parent} {
    m_topLayout.addWidget(&m_sign, 0, 0);
  }
};

你正在傳遞指針,但對象所有權是明確的,所有權沒有變化。 僅僅因為QObject具有父級並不意味着父級“擁有”它。 如果孩子在父母之前遭到破壞,則所有權停止。 通過使用C ++語義 - 即明確定義的成員構造和破壞順序 - 您可以完全控制子生存期,並且沒有QObject父級可以干涉。

如果您有一個擁有一個所有者的不可移動對象,請使用std::unique_ptr並移動它。 這是圍繞您自己的代碼傳遞動態創建的QObject的方法。 您可以在指向由QObject父級管理其所有權的位置從指針中刪除它們(如果有的話)。

如果您擁有共享所有權的對象,其生命應該盡快結束(與應用程序終止時相比,或者某些長期存在的對象被破壞),請使用std::shared_ptr 確保指針超過用戶。 例如:

class MyData : public QAbstractItemModel { /* ... */ };

class UserWindow : public QWidget {
  Q_OBJECT
  std::shared_ptr<MyData> m_data; // guaranteed to outlive the view
  QTreeView m_view;
public:
  void setData(std::shared_ptr<MyData> && data) {
    m_data = std::move(data);
    m_view.setModel(m_data.data());
  }
};

這個例子可能是人為的,因為在Qt中,大多數對象用戶都會觀察對象的destroyed()信號並對對象的destroyed()作出反應。 但是,如果例如m_view是第三方C API對象句柄,無法跟蹤數據對象的生命周期,則這是有道理的。

如果對象的所有權是跨線程共享的,那么使用std::shared_ptr是必不可少的: destroyed()信號只能在單個線程中使用。 當您在另一個線程中獲知有關對象刪除的消息時,為時已晚:該對象已被破壞。

第三,當你從工廠方法返回動態創建的對象的實例時,你應該通過一個裸指針返回它們:很明顯,工廠創建了一個供其他人管理的對象。 如果您需要異常安全性,則可以返回std::unique_ptr

對於首發,在羅馬,是羅馬人。
QT是在90年代初開發的,並且一次取得了巨大的成功。
不幸的是,隨着時間的推移,QT並沒有真正采用新的功能,因此API本身具有非常古老的C ++風格(我可以說,它是一種Java風格嗎?)

你不能強迫QT突然變成C ++ 14,因為它不是。 在QT方面使用流行的QT約定。 如果這是平台設計目標,請使用原始指針。 不能使用值類型。

但我不認為你使用C ++ 14讓QT工作得那么多。 堅持平台給出的QT習語。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM