[英]two std::shared_ptr from the same raw pointer
我不明白為什么要explicit shared_ptr( pointer p );
不能保護開發人員不要將p分配給另一個shared_ptr
。
我的想法在這里:
#include <iostream>
#include <memory>
template <typename T>
class ptr
{
public:
// ctor a) for lvalues
explicit ptr(T*& value) : value_(value) { value=nullptr; }
// ctor b) for rvalues pointer reference
explicit ptr(T*&& value) : value_(value) { }
~ptr() { delete value_; }
// for simplicity this is left public
T* value_;
};
int main(int argc, char *rgv[])
{
{
printf("%10s | %10s | %10s\n", "raw", "p0", "p1");
// create a raw pointer
// BAD practice but still could happen
int* raw = new int(1);
printf("%10x | %10x | %10x\n", raw, 0, 0);
// init p0 from raw pointer ctor (a)
ptr<int> p0(raw);
printf("%10x | %10x | %10x\n", raw, p0.value_, 0);
// init p1 from the same raw poiter again ctor (a)
ptr<int> p1(raw);
printf("%10x | %10x | %10x\n", raw, p0.value_, 0);
// nothing bad happens val was set to nullptr
// before p1 construction
}
// in order to construct ptr from rvalues
// we use ctor (b)
ptr<int> p2(new int());
{
printf("\n");
// create a raw pointer
int* raw = new int(1);
printf("%10x | %10x | %10x\n", raw, 0, 0);
// init p0 from raw pointer
std::unique_ptr<int> p0(raw);
printf("%10x | %10x | %10x\n", raw, p0.get(), 0);
// init "accidentally" p1 from the same raw poiter again
std::unique_ptr<int> p1(raw);
printf("%10x | %10x | %10x\n", raw, p0.get(), 0);
// CRASH: double free or corruption
}
return 0;
}
鑒於以上代碼,我有兩個問題:
1)我是否錯過了以這種方式實施ptr的任何要點:簡而言之,我對ptr(T*& value)
和ptr(T*&& value)
建設者有什么看法嗎?
2)STL決定不避免這種可能的錯誤而導致原始指針在shared_ptr
構造上保持不變的背后的原理是什么?
我是否錯過了以這種方式實施ptr的任何要點?
例如,如果必須將類型轉換應用於指針
struct Base {/*...*/};
struct Derived : Base {/*...*/};
Derived * d = new Derived;
ptr<Base> p(d);
那么臨時Base
指針將傳遞給rvalue構造函數,而d
將被保留。
(您可以使用模板構造函數來解決這個問題,但是可能還有其他子屬性)。
當然,如果用戶愚蠢到可以保留一個原始指針,那么他可能愚蠢到可以保留兩個原始指針。 該方案只會使其中之一無效。
STL決定不避免這種可能的錯誤,從而使原始指針在
shared_ptr
構造上保持不變的背后的原理是什么?
大概是最少驚奇的原則。
通過區分智能指針和原始指針,並始終將原始指針視為危險的野獸,可以避免此類錯誤。 這樣的局部安全網只會使發現咬傷的細微邊緣情況變得更加困難。 智能指針的慣用用法避免了原始指針,除非在異常情況下(需要特別注意),否則完全消除了與所有權相關的錯誤的可能性。
在C ++ 14中, std::make_unique
(除了我們已經擁有的std::make_shared
)將意味着根本不需要在代碼中出現任何new
,從而很容易避免此錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.