![](/img/trans.png)
[英]recreate(reassign) a std::shared_ptr or std::unique_ptr
[英]assymetry between std::shared_ptr and std::unique_ptr constructors
在C ++ 03中,我們沒有unique_ptr
,所以我改用了tr1::shared_ptr
。
現在,在C ++ 11中,在這種情況下,我將替換這樣的調用:
tr1::shared_ptr<X> o(new X);
同
std::unique_ptr<X> o(new X);
不幸的是,由於某種原因,我無法替換包含刪除器的情況,其中刪除器是一個函數:
void special_delete(Y *p) { ... }
tr1::shared_ptr<Y> o(new Y(), special_delete);
std::unique_ptr<Y> o(new Y(), special_delete); // does not compile
std::unique_ptr<Y, std::function<void(Y*)> > o(new Y(), special_delete); // this compiles
為什么會這樣? 是否可以使用unique_ptr構造函數替換所有shared_ptr構造函數的同類方法?
我已經創建了這個 ,但是對此我並不是很滿意。
template <class Y>
using unique_ptr_with_deleter = std::unique_ptr<Y, std::function<void(Y*)> >;
unique_ptr_with_deleter<Y> o(new Y(), special_delete); // this compiles
shared_ptr
模板對刪除程序進行類型擦除。 您想要的任何一種刪除器只有一個單一類型shared_ptr<T>
。 這是一個非常重(且昂貴)的工具。
相比之下, unique_ptr
成為該類型的刪除器部分,因此沒有動態調用開銷。 unique_ptr<T, D>
與原始指針幾乎一樣便宜。
請注意,可以為任何刪除程序類型D
從unique_ptr<T, D>
右值構造一個shared_ptr<T>
。
關於您的解決方案的隨機評論:兩種解決方案都不是很好。 使用函數指針作為刪除器,不必要地使刪除器成為您unique_ptr狀態的動態部分。 std::function
情況甚至更糟,使用整個類型擦除的虛擬調度機制進行刪除-請記住,您靜態地知道如何刪除!
更好的解決方案是通過編寫自己的類型 ,使deleter成為type的一部分,而不是value的一部分:
struct YDeleter { void operator()(Y* p) { special_delete(p); } };
std::unique_ptr<Y, YDeleter> p(new Y); // or presumaby some special factory
這樣,整個刪除邏輯在編譯時就已知,並且可以盡可能內聯,而無需其他函數調用間接。
您應該提供刪除器類型
std::unique_ptr<Y, decltype(&special_delete)> o{new Y{}, &special_delete};
請注意,替換tr1::shared_ptr<X> o(new X);
與std::unique_ptr<X> o(new X);
這不是一個好主意,也不應該在總體上起作用。 std::unique_ptr
更像是auto_ptr
的替代品。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.