簡體   English   中英

Qt信號:將動態分配的參數的所有權傳遞給插槽?

[英]Qt Signals: Passing ownership of dynamically allocated argument to a slot?

我不知道如何准確地稱呼這個問題,所以這里是解釋:

我有一個自定義小部件,當完成編輯后,該小部件會發出一個帶有根據用戶輸入構建的自定義對象的信號,例如

void GGActionEditor::finishEditing() {
  GGAction act;
  // Set up according to user input
  emit actionChanged(act);
}

在此代碼中,連接到單個對象的接收器可以存儲該對象的副本或以任何合適的方式對其進行處理,而小部件可以忽略它。

但是,當小部件可以通過類層次結構構建不同類型的對象時,如何處理這種情況呢? 喜歡:

void GGActionEditor::finishEditing() {
  GGAction *pAct;
  // Create and set up according to user input, e.g.
  if (...) pAct = new GGSpecialAction;
  else pAct = new SimpleAction;
  emit actionChanged(pAct);
}

在這種情況下處理對象生命周期的最佳解決方案是什么? 小部件無法知道是否有任何接收者接管了Action對象。 同樣,如果連接了多個接收器,它們都不知道是否有另一個對象接管了該參數...
在“最佳”情況下,這可能會導致泄漏; 但是也會導致該參數被多次刪除。

更新:
有關我的實際情況的更多信息,但是,我也對常規解決方案感興趣:

傳遞的對象將由接收器存儲,並保留在應用程序的域模型中。 該模型將負責以后刪除它。
簡單的解決方案是像上述“簡單的”按值情況一樣處理這種情況。 但是,如果根本沒有連接任何接收器,則該物體會泄漏; 並且沒有100%保證只有1個接收者會這樣做(在我的實際應用邏輯中會是這種情況,但是既不能檢查也不能以這種方式執行)。

我想出了一些可能的解決方案,並對任何評論或補充內容感興趣:

  1. 只是希望它能解決
    假設將有1個接收器來接管該參數。 這可能適合我的應用程序,但我對此不滿意
  2. 使用共享指針
    正如Eugene在回答中所說,shared_ptr(或QSharedPointer)將簡化這一過程。 任何接收者和發送者都將使用共享的指針,因此生命周期是自動管理的。 但這迫使我的域模型也為持有此類Action對象的每個類使用共享指針。 這不太適合我的模型,因為這些類應該匯總操作。 共享指針不適用於持有對“屬於”該對象的對象的引用。
  3. 添加指示超車的參數
    在信號中添加bool* ,以指示是否有接收者接管了該操作。 接收者知道,如果該值為真,它將無法再超過它。 此外,如果沒有接收者接收,則發送方知道是否應刪除該對象。 但是,哪個接收者以先到先得的方式獲取對象是非常隨機的。 而且它污染了界面...
  4. 對不同的具體類別使用不同的信號
    在這種情況下,接收方的插槽可以知道使用了哪個具體子類並制作了該對象的副本。 但是,這為使用類層次結構可以很好地完成的事情添加了額外的信號/插槽。此外,每個子類都必須有一個復制控制器。
  5. 向類添加一個clone方法
    與上述類似,但只有1個信號。 多態clone將創建具體子類的副本。
  6. 使用專用接口代替信號/插槽
    做一個GGIActionReceiver類,並在指定最多1個實例GGActionEditor 該實例是接管Action對象的唯一合格對象。 仍然可以發信號通知其他人,但是他們一定不能超越指針。 這樣,發送者還知道是否必須刪除對象(未設置接收者)

這里的一種選擇是通過std :: shared_ptr <>或其他一些引用計數機制來使用共享所有權。 這樣,只要有人需要,該對象就可以生存。

Qt的正常所有權模型不太有效,因為您無法確定有多少個信號用戶希望擁有同一對象的所有權。

取決於您的邏輯,共享所有權可能導致閉環,並打破閉環,您可能被迫在一個或兩個抽象中打洞。

確保不要將Qt所有權與shared_ptr混合使用-您的QObject不能有父級。

暫無
暫無

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

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