简体   繁体   English

共享指针和原始指针生命周期

[英]shared pointer and raw pointer lifetime

Could someone explain simply the reason why this does not work:有人可以简单地解释一下为什么这不起作用的原因:

std::shared_pointer<Bar> getSharedPointer() {
    return std::make_shared<Bar>();
}

...

auto foo = getSharedPointer().get();

Apparently using the raw pointer foo will cause a segfault because the lifetime of the shared pointer returned by getSharedPointer() will have run out.显然,使用原始指针foo会导致段错误,因为getSharedPointer()返回的共享指针的生命周期将耗尽。 Somehow I would expect it to last until the end of its scope (like whatever block it is inside).不知何故,我希望它持续到它的范围结束(就像它里面的任何块一样)。

Is this correct and are there any analogous examples to this situation?这是正确的,有没有类似的例子?

For getSharedPointer().get();对于getSharedPointer().get(); , getSharedPointer() returns a temporary std::shared_ptr which will be destroyed after the expression immediately, and the pointer managed by it will be deleted too. , getSharedPointer()返回一个临时的std::shared_ptr ,它会在表达式之后立即被销毁,并且它所管理的指针也会被删除。 After that foo will become dangled, any dereference on it causes UB.foo将变为悬空之后,对它的任何取消引用都会导致 UB。

auto foo = getSharedPointer().get();
// foo have become dangled from here

You could use a named variable instead:您可以改用命名变量:

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();

Whenever a function returns a type that is not a reference, the result of calling the function is an rvalue.每当一个函数返回一个不是引用的类型时,调用该函数的结果就是一个右值。 Also, because the function getSharedPointer() returns a class type, the result is a temporary object.此外,因为函数getSharedPointer()返回一个类类型,所以结果是一个临时对象。

The lifetime of that temporary object is defined as the end of the evaluation of the outermost expression, here getSharedPointer().get() .该临时对象的生命周期被定义为最外层表达式的计算结束,这里是getSharedPointer().get() As soon as the foo variable is initialized, the owning smart pointer is destroyed;一旦foo变量被初始化,拥有的智能指针就会被销毁; when the last shared_ptr owning that object is destroyed, the object is deleted.当最后一个拥有该对象的shared_ptr被销毁时,该对象将被删除。

Here getSharedPointer() always returns shared_ptr that doesn't share the managed object ( use_count() is 1), so when that copy of the last shared_ptr is destroyed, the object is destroyed and the pointer to the object is invalid.这里getSharedPointer()总是返回不共享托管对象的shared_ptruse_count()为 1),因此当最后一个shared_ptr副本被销毁时,该对象被销毁并且指向该对象的指针无效。

(I am not sure why you are returning a shared_ptr and not a unique_ptr here.) (我不确定你为什么在这里返回shared_ptr而不是unique_ptr 。)

The proper use of a smart pointer, or any class that "owns" (controls the lifetime of) other resources (resources that you are still allowed to access directly), is to keep the "smart" pointer/owner alive as long as you need to access the ressource.正确使用智能指针或任何“拥有”(控制其生命周期)其他资源(您仍然可以直接访问的资源)的类,是让“智能”指针/所有者保持活动状态,只要您需要访问资源。

So the "smart" pointer (owning object) needs to be named.因此需要命名“智能”指针(拥有对象)。 Also, I am not sure that you really would want to hide the fact that it is a smart pointer from the view of the reader with auto .另外,我不确定您是否真的想隐藏它是带有auto的阅读器视图中的智能指针这一事实。

std::shared_pointer<Bar> foo = getSharedPointer();
// use foo.get()

You may want to hide the exact type of managed object:您可能想要隐藏托管对象的确切类型:

std::shared_pointer<auto> foo = getSharedPointer();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM