有人可以简单地解释一下这不起作用的原因吗:
std::shared_pointer<Bar> getSharedPointer() {
return std::make_shared<Bar>();
}
...
auto foo = getSharedPointer().get();
显然,使用原始指针foo
将导致段错误,因为getSharedPointer()
返回的共享指针的生存期将用完。不知何故,我希望它能持续到其范围的尽头(就像它里面的任何块一样)。
这是否正确,是否有类似的例子?
对于getSharedPointer().get();
,getSharedPointer()
返回一个临时std::shared_ptr
,该将在表达式之后立即销毁,并且由它管理的指针也将被删除。之后foo
将变得悬空,对其的任何取消引用都会导致 UB。
auto foo = getSharedPointer().get();
// foo have become dangled from here
您可以改用命名变量:
auto spb = getSharedPointer();
auto foo = spb.get();
// It's fine to use foo now, but still need to note its lifetime
// because spb will be destroyed when get out of its scope
// and the pointer being managed will be deleted too
auto foo = getSharedPointer().get();
每当函数返回不是引用的类型时,调用该函数的结果就是右值。此外,由于函数getSharedPointer()
返回类类型,因此结果是一个临时对象。
该临时对象的生存期定义为最外层表达式的计算结束,此处getSharedPointer().get()
。一旦初始化foo
变量,拥有的智能指针就会被销毁;当拥有该对象的最后一个shared_ptr
被销毁时,该对象将被删除。
在这里,getSharedPointer()
始终返回不共享托管对象的shared_ptr
(use_count()
为 1),因此当销毁最后一个shared_ptr
的副本时,对象将被销毁,指向该对象的指针无效。
(我不确定你为什么在这里返回shared_ptr
而不是unique_ptr
。
正确使用智能指针或任何"拥有"(控制)其他资源(仍允许您直接访问的资源)的类是为了使"智能"指针/所有者保持活动状态,只要您需要访问资源。
因此,需要命名"智能"指针(拥有对象)。另外,我不确定您是否真的想从读者的视野中隐藏它是一个智能指针的事实auto
.
std::shared_pointer<Bar> foo = getSharedPointer();
// use foo.get()
您可能希望隐藏托管对象的确切类型:
std::shared_pointer<auto> foo = getSharedPointer();