我不知道如何正確地標題這個問題,所以這裏是解釋:Qt信號:將動態分配參數的所有權傳遞給插槽?
我有一個自定義小部件發出一個信號與用戶的輸入內置的自定義對象,編輯完成後,例如,
void GGActionEditor::finishEditing() {
GGAction act;
// Set up according to user input
emit actionChanged(act);
}
在該代碼中,連接到所述接收器葛可存儲對象或過程中它的副本以任何方式認爲合適的,並且小部件可以忘記它。
但是,如何處理這種情況,當小部件可以構建不同類型的對象來自類hierachry?像:
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對象。另外,如果連接了多個接收器,它們都不知道另一個對象是否接管了參數...
在「最佳」情況下,這會導致泄漏;但也可能導致該參數被多次刪除。
更新:
我的實際情況,一些更多的信息,但是,我也有興趣在通用的解決方案:
傳遞的對象將被接收機存儲並保存在應用程序的域模型。該模型將在稍後刪除它。
簡單的解決方案就是處理這種情況,就像上面所描述的「簡單」by-value情況。但是,如果根本沒有接收器連接,則該對象會泄漏;並沒有100%的保證,只有1個接收者會這樣做(在我的實際應用邏輯中將是這種情況,但它不能通過這種方式來檢查和強制執行)。
,我想出了一些可能的解決方案,並有興趣的任何意見或補充:
- 只是希望它會工作了:
假設會有正好1個接收器,接管參數。這可能會爲我的應用程序工作得很好,但我不覺得喜歡它 - 使用共享指針:
正如尤金在回答中,shared_ptr的(或QSharedPointer)表示將簡化這一點。任何接收者和發送者都將使用共享指針,因此生命週期會自動進行管理。但是這迫使我的域模型也爲每個擁有這樣一個Action對象的類使用一個共享指針。這不適合我的模型,因爲這些類應該聚合這個動作。共享指針不用於保持參考的對象「屬於」的對象感覺右......指示 - 添加參數超車:
添加bool*
於該信號,其指示如果一些接收器具有接管了行動。一個接收者知道它不能超過它,如果這個值是真的。此外,發件人知道是否應該刪除該對象,如果沒有收件人採取了。但是,接收者會以先到先得的方式接受客體是非常隨意的。它會污染界面...... - 使用不同的具體類不同的信號:
在這種情況下,接收器的插槽可以知道使用其具體子類,使對象的副本。但是,這增加了額外的信號/插槽,用於使用類層次結構可以很好地完成的任務......並且每個子類都必須有一個copy-c'tor。 - 添加
clone
方法到類:
類似於上面,但只有1個信號。多態性clone
將創建具體子類的副本。 - 使用一個專門的接口,而不是信號/插槽:
做一個GGIActionReceiver
類,並在GGActionEditor
分配最多1個實例。此實例是唯一可以接管Action對象的可接受對象。其他人仍然可以發出信號,但他們不能超過指針。這樣,發件人也知道是否必須刪除對象(沒有設置接收器)
是否所有接收器與發射器處於同一線程中(actionChanged(pAct)'是同步的)?如果是這樣,你可以在末尾放置'delete pAct;'行。 –
是的,它們在同一個線程中。但在我的情況下,很可能(如果不是確定的話)其中一個接收器將保持對象(如我的更新中所述) –