c++ primer fifth edition说道:与shared_ptr不同,没有像make_shared那样返回unique_ptr的库函数。相反,当我们定义unique_ptr时,我们将其绑定到返回bu new 的指针。但是下面的代码可以编译运行,为什么?
int ix = 1024, * pi = &ix; unique_ptr<int> uq1(pi);
kpbpu0081#
unique_ptr可以指向普通指针吗?是的,它们可以。尽管通常它们指向动态分配的对象,而这些对象本身并不是指针(动态分配指针很少有意义)。智能指针通过封装指向该对象的原始指针来实现这一点。尽管这只是对标题措辞的吹毛求疵,所以请继续阅读。你的代码与你引用的语句并不矛盾,尽管代码是错误的。考虑一下当变量超出作用域时会发生什么:
{ int ix = 1024, * pi = &ix; std::unique_ptr<int> uq1(pi); } // <-
在作用域结束时,第一个uq1将被销毁。在内部,它在指针上调用delete。这是未定义的行为,因为您只能delete通过new创建的对象。在C++14之前,正确的代码是:
uq1
delete
new
{ int* pi = new int(1024); std::unique_ptr<int> uq1(pi); }
pi指向动态分配的int。所有权转移到智能指针,然后在析构时调用delete。像上面一样,通过显式调用new有几个缺点。例如,它与返回std::shared_ptr的std::make_shared()不一致。在C++14中,引入了std::make_unique():
pi
int
std::shared_ptr
std::make_shared()
std::make_unique()
{ auto uq1 = std::make_unique<int>(1042); }
你引用的文字指的是C++14之前的一段时间,当时“没有一个库函数可以与make_shared相媲美,并返回一个unique_ptr”。
1条答案
按热度按时间kpbpu0081#
unique_ptr可以指向普通指针吗?
是的,它们可以。尽管通常它们指向动态分配的对象,而这些对象本身并不是指针(动态分配指针很少有意义)。智能指针通过封装指向该对象的原始指针来实现这一点。尽管这只是对标题措辞的吹毛求疵,所以请继续阅读。
你的代码与你引用的语句并不矛盾,尽管代码是错误的。
考虑一下当变量超出作用域时会发生什么:
在作用域结束时,第一个
uq1
将被销毁。在内部,它在指针上调用delete
。这是未定义的行为,因为您只能delete
通过new
创建的对象。在C++14之前,正确的代码是:
pi
指向动态分配的int
。所有权转移到智能指针,然后在析构时调用delete
。像上面一样,通过显式调用
new
有几个缺点。例如,它与返回std::shared_ptr
的std::make_shared()
不一致。在C++14中,引入了std::make_unique()
:你引用的文字指的是C++14之前的一段时间,当时“没有一个库函数可以与make_shared相媲美,并返回一个unique_ptr”。