![](/img/trans.png)
[英]Why does unique_ptr have the deleter as a type parameter while shared_ptr doesn't?
[英]Why unique_ptr doesn't prevent slicing of custom deleter?
具有custom deleter
的std::unique_ptr
的行為基於custom deleter
器的靜態類型 。 沒有多態性,沒有基於在運行時傳遞的實際刪除器的運行時行為,因為提供的派生刪除器被切片到聲明的刪除器的靜態類型。
(它以這種方式設計,允許使用
default deleter
的unique_ptr的大小或custom deleter without any data members
大小,以使其具有與原始指針相同的大小)。
custom deleter
的unique_ptr
靜態行為: class A {};
struct BaseDeleter {
virtual void operator()(A* p) const {
std::cout << "in BaseDeleter" << std::endl;
delete p;
}
};
struct DerivedDeleter: BaseDeleter {
void operator()(A* p) const override {
std::cout << "in DerivedDeleter" << std::endl;
delete p;
}
};
int main() {
auto unique_var = std::unique_ptr<A, BaseDeleter>(new A);
unique_var = std::unique_ptr<A, DerivedDeleter>(new A);
}
輸出:
in BaseDeleter
in BaseDeleter
這與std::shared_ptr
相反,后者以不同方式保存自定義刪除器並允許動態行為:
shared_ptr
與custom deleter
動態行為: int main() {
auto shared_var = std::shared_ptr<A>(new A, BaseDeleter{});
shared_var = std::shared_ptr<A>(new A, DerivedDeleter{});
}
輸出:
in BaseDeleter
in DerivedDeleter
代碼: https : //coliru.stacked-crooked.com/a/54a8d2fc3c95d4c1
使用不同的custom deleter
分配std::unique_ptr
的行為實際上是切片 。
如果指定的unique_ptr具有不同的custom deleter
,為什么語言不會阻止std::unique_ptr
的賦值,以避免切片?
這似乎是可能的,如下所示。
unique_ptr
切割custom deleter
template<typename TYPE, typename Deleter>
struct my_unique_ptr : std::unique_ptr<TYPE, Deleter> {
using BASE = std::unique_ptr<TYPE, Deleter>;
using std::unique_ptr<TYPE, Deleter>::unique_ptr;
auto& operator=(std::nullptr_t) noexcept {
return BASE::operator=(nullptr);
}
template<typename T, typename OtherDeleter,
std::enable_if_t<!std::is_same<OtherDeleter, Deleter>::value>* dummy = nullptr>
auto& operator=(std::unique_ptr<T, OtherDeleter>&& other) = delete;
};
struct B {
virtual ~B() = default;
};
struct D : B {};
std::unique_ptr<B> b;
b = std::make_unique<D>();
這里我們有一個經典的用例。 是的,刪除器被切片,但刪除仍然很明確。 你的提議會干擾這一點。 並且可能很難可靠地修改為不干擾。
可以隨時指定一個自定義刪除器,如std::function<void(void*)>
以通過類型擦除獲得多態性。 當然,它有開銷,但這是選擇。
默認情況下, unique_ptr
針對更常見的用例進行了優化,不常見的用例需要通過請求進行開銷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.