[英]error when defining a std::shared_ptr with new operator
我試圖用以下方式用new
運算符定義std::shared_ptr
:
#include <memory>
struct A {
};
int main() {
std::shared_ptr<A> ptr = new A();
return 0;
}
但我獲得了以下編譯時錯誤:
main.cpp:在函數'int main()'中:
main.cpp:8:30:錯誤:從'A *'轉換為非標量類型'std :: shared_ptr'請求std :: shared_ptr ptr = new A();
無論如何,以下肯定有效:
std::shared_ptr<A> ptr{new A()};
你們中有誰知道為什么會這樣嗎?
tl; dr:這是相關構造函數explicit
。
使用=
初始化時,將調用復制初始化。 C ++不允許從原始指針復制初始化shared_ptr
,因為從一些任意原始指針到不實際管理它的shared_ptr
的意外隱式轉換最終會很容易。
這樣,你可以將一個原始指針“捕獲”到shared_ptr
的唯一方法就是非常謹慎而且非常明確(正如你在第二個例子中所做的那樣)。 現在,只有在這個初始化器中,你必須記住不要使用你已經在其他地方管理過的指針。
特定行std::shared_ptr<A> ptr = new A()
有什么危險嗎? 不,但你所看到的是各種C ++規則協同工作的結果。
你可以把你的陳述想象成像這樣的2班輪。
A* a = new A();
std::shared_ptr<A> ptr = a;
雖然在這種情況下,這可能在更復雜的代碼中是正確的,但它可能導致潛在的陷阱,因此不允許復制初始化到原始指針。
想像
A* a = new A();
//.....
std::shared_ptr<A> ptr = a;
//.....
std::shared_ptr<A> ptr2 = a; //second ptr holding a... UB
在這里你將有2個共享指針持有相同的對象,這會導致麻煩。
為了避免那些“隱式”錯誤,C ++不允許這種初始化。
雖然你仍然可以使用構造函數,但它更“冗長”,更難以意外地分配指針。
std::shared_ptr<A> ptr{ new A() };
這看起來更像是構建一個新對象,並且可能不會導致意外錯誤分配。
在現代創建共享指針的首選方法是
auto ptr = std::make_shared<A>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.