簡體   English   中英

std :: shared_ptr和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>與原始指針幾乎一樣便宜。

請注意,可以為任何刪除程序類型Dunique_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.

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