有人可以解释为什么这不起作用的原因:
std::shared_pointer<Bar> getSharedPointer() {
return std::make_shared<Bar>();
}
...
auto foo = getSharedPointer().get();
显然使用原始指针foo
会导致段错误,因为getSharedPointer()
返回的共享指针的生命周期将耗尽。不知怎的,我希望它能持续到它的范围结束(就像它里面的任何一块)。
这是正确的吗?这种情况有没有类似的例子?
答案 0 :(得分:7)
对于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
答案 1 :(得分:1)
auto foo = getSharedPointer().get();
每当一个函数返回一个不是引用的类型时,调用该函数的结果就是一个rvalue。此外,因为函数getSharedPointer()
返回类类型,结果是临时对象。
该临时对象的生命周期定义为最外层表达式的评估结束,此处为getSharedPointer().get()
。一旦初始化foo
变量,就会销毁拥有的智能指针;当拥有该对象的最后一个shared_ptr
被删除时,该对象将被删除。
此处getSharedPointer()
始终返回不会共享托管对象的shared_ptr
(use_count()
为1),因此当最后一个shared_ptr
的副本被销毁时,对象被破坏,指向对象的指针无效。
(我不确定您为什么要在这里退回shared_ptr
而不是unique_ptr
。)
正确使用智能指针,或任何&#34;拥有&#34; (控制其生命周期)其他资源(您仍然可以直接访问的资源),是保持&#34; smart&#34;只要您需要访问资源,指针/所有者就会生效。
所以&#34; smart&#34;指针(拥有对象)需要命名。此外,我不确定你是否真的想隐藏这个事实,即它是auto
读者视角的智能指针。
std::shared_pointer<Bar> foo = getSharedPointer();
// use foo.get()
您可能希望隐藏托管对象的确切类型:
std::shared_pointer<auto> foo = getSharedPointer();