2013-02-10 58 views
2

我有一個繼承自enable_shared_from_this的類。它有shared_ptr s到子對象,並有一個「根」對象,所以整個層次結構由shared_ptr管理。這樣一個對象可以有多個父母並被安全地破壞。由shared_ptr管理的對象的C++隱藏構造函數

我開始寫一個構造函數,然後我意識到用戶應該像使用std::shared_ptr一樣管理對象,就像我在內部做的一樣,就像我在一些現有的庫中看到的一樣,例如gtkmm。所以我可以做我看到別人做的事情:隱藏構造函數,並編寫一個靜態成員函數create(),它返回一個shared_ptr到新對象。很明顯create()是非常有用的,因爲沒有它我需要調用std::make_shared()或更高版本std::shared_from_this()

但是我應該隱藏構造函數,爲什麼?我可以猜出一些很好的理由,例如它強制用戶使用shared_ptr,否則該對象被刪除,所以它保證用戶不使用不受shared_ptr管理的「孤立」對象。它確保用戶不會忘記手動創建shared_ptr,因爲遺忘意味着對象被刪除,即使它被複制(深層複製,而不是指針的副本),然後用戶會很快注意到這一點。

另一個有趣的選擇是沒有create()靜態方法,而是使用add_child()方法成爲創建新對象的唯一方法。這保證了它與層次結構相關聯。問題:靈活性。如果有人想單獨使用一個對象,那麼這是不可能的,除非你派生類。

你會/我該做什麼?隱藏/不隱藏ctor? add_child()create()

+1

你似乎有利弊得出相當好。如果類**需要**由'shared_ptr'管理,我會隱藏構造函數。 – 2013-02-10 22:43:11

+0

@DrewDormann在我的用例中,所有對象都在層次結構中,但總的來說,我不知道。唯一可以說的方式是共享內存和對象的體驗,這是我沒有的。像gtkmm這樣的庫隱藏了ctor - 堅持下去,我想我明白了!隱藏ctor有一個很好的理由:防止用戶意外地在共享對象上調用delete。使用隱藏的ctor只能在明確調用shared_ptr :: get()時纔會發生:) – cfa45ca55111016ee9269f0a52e771 2013-02-10 22:49:48

+0

但是仍然存在一個問題:make create()是公開還是限制用戶使用add_child()? – cfa45ca55111016ee9269f0a52e771 2013-02-10 22:51:15

回答

1

在一般情況下,沒有一個正確的答案。你可以從編寫所有這些方法開始:構造函數,create()和create_child(),都是公共的。然後,在使用界面的時候,最好在測試它的時候(如果可能的話,在你使用「真實」代碼之前完成它),檢查不同構造選項的可能副作用,結果和方便性,並決定什麼是最好的和安全的,針對您的特定用例。

如果所有人都安全,你可以將他們三人全部公開。否則,通過隱藏不安全的隱私(或者可能受到保護,如果它是要派生的類的構造函數),並將安全的隱藏給用戶使用。