簡體   English   中英

std :: unique_ptr和reset()還是您的類的Reset方法?

[英]std::unique_ptr and reset() or a Reset method for your class?

使用std::unique_ptr::reset ,您可以輕松地將實例恢復到新狀態。

在C ++ 11之前的版本中,為了實現類似的行為,我已經看到很多類定義了一個Reset()方法來重置其所有內部成員。 但是現在,我認為只需構造函數和析構函數,並將unique_ptr reset為該類的新實例,就可以實現相同的目的。 為什么您仍然偏愛Reset()方法,或者我應該總是只使用unique_ptr並將其reset為新實例,以便何時“重置”類,所以我是否缺少任何好處?

我能想到的唯一好處是您節省了分配/刪除,這有時可能會很昂貴。 當然,代價是維護Reset()函數並確保其與其他代碼更改保持最新的復雜性。

是嗎 這只是一個復雜性與性能問題?

這是將類的狀態重置為其默認構造狀態的一種非常好的通用方法:

// Previously constructed MyClass myvalue = ...
myvalue = MyClass{};

這涉及兩個操作:

  1. 默認構造。
  2. 移動作業。

理想情況下,這兩個都應該便宜。

我能想到的唯一好處是您節省了分配/刪除操作,這有時可能會很昂貴

在頻繁的重置過程中,不僅分配可能會很昂貴,而且可能會導致內存碎片化,錯誤的局部性(由於在我的腦海中搜索的術語是@Cris),最終會帶來巨大的性能問題。

unique_ptr根本不是要重置您的實例狀態。 unique_ptr::reset重置的所有權 unique_ptr ,這是后果調用析構函數中的“老字號”的實例。

因此,這與您的實例Reset方法完全不同。

重置時

  • 你不實例化一個新的內存->親

  • 潛在的可以重復使用相同的內存,而不搗毀,所以保持數據一致和緊湊(取決於你如何 implment你的Reset方法) - >親

  • 不安全的內存管理,導致內存泄漏->缺點

如果是unique_ptr

  • 無指針別名和內存管理控制-> pro
  • 每次分配新實例->缺點

所有優點缺點自然可以爭論,取決於具體的實現和實際要求。

分配/刪除是一種成本,但也存在通過指針訪問對象的額外間接級別的成本。 例如較差的數據位置。

還可以在僅具有引用或指針的上下文中調用Reset()函數。 唯一應了解某個對象正在由unique_ptr管理的對象是所有者。 在其他情況下,最好使用引用或指針。

但是,只要您知道費用,而且只有房主想進行重置,我認為這樣做沒有任何問題。

當然,這在C ++ 11中不是什么新事物,使用堆分配的對象總是可以做到這一點。 這只是unique_ptr如何使生活更輕松的一個示例。

我認為您在這里混淆了一些事情。

shared_ptr這樣的unique_ptr是代表所有權的結構。 使用unique_ptr意味着您的類既不能復制也不能復制分配給您,除非您自己提供復制構造函數和復制賦值運算符。 但是,這將是額外的工作。

因此,如果您仍然想提供一個reset方法,但又不想手工重置每個成員變量,則可以執行以下操作:

MyClass::Reset()
{
    this->~MyClass();
    new(this) MyClass();
}

這會將您的實例重置為其默認創建狀態。

這種方法的缺點是

  • 不保存異常,因此,如果構造函數拋出異常,則會出現問題。
  • 您的成員在內部使用的動態內存將被丟棄,不能直接重用。 例如,釋放堆中的vector成員及其關聯的內存,而不是重用它們。

事實上,你也可以實現Reset一樣

MyClass::Reset()
{
    *this = MyClass();
}

盡管那可能比以前的解決方案要慢。

暫無
暫無

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

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