此示例中的'aliased local shared_ptr'是什么

What is an 'aliased local shared_ptr' in this example

本文关键字:shared ptr 是什么 local aliased      更新时间:2023-10-16

我有一个关于Cpp核心指南中的例子的问题。在 R.37: 不要传递从别名智能指针获取的指针或引用中,有以下示例:

// global (static or heap), or aliased local ...
shared_ptr<widget> g_p = ...;
void f(widget& w)
{
g();
use(w);  // A
}
void g()
{
g_p = ...; // oops, if this was the last shared_ptr to that widget, destroys the widget
}

而且我不明白第一条评论中的"别名本地"是什么意思。它是否连接到混叠指针类型,例如

using WidgetPtr = std::shared_ptr<widget>;

还是我完全走错了路?我想我理解这个全局shared_ptr的例子,但不是别名本地的例子。

当指向该对象的所有std::shared_ptr都被销毁或重新分配给其他对象时,std::shared_ptr将自动销毁它指向的对象。

这意味着,如果存储指针或对由std::shared_ptr管理的对象的引用(这是一个锯齿指针(,如果管理它的std::shared_ptr被销毁或修改,它可能会突然变得悬空。

您省略了示例中最重要的部分,但在以下情况下:

std::shared_ptr<int> shared = std::make_shared<int>(7);
int& ptr = *shared;
shared = nullptr;

shared设置为nullptr时,它指向的对象会立即被销毁,这意味着任何指向它的指针(如ptr(现在都悬空,读取或写入它将导致 UB。

const shared_ptr<widget>& alias = g_p;g_p的别名。代码中没有别名的本地shared_ptr,他们只是为了完整性而提到它:你不能通过创建指向全局变量的引用或指针来回避这个问题(或多或少只是在本地范围内给它一个不同的名称 - 别名(。

它与像您的WidgetPtr这样的类型别名无关(尽管当然可以使用类型别名来创建全局shared_ptr的本地别名,但这是正交的(。

换句话说:如果这是错误的代码:

void bad_code()
{
// BAD: passing pointer or reference obtained from a nonlocal smart pointer
//      that could be inadvertently reset somewhere inside f or it callees
f(*g_p);
// BAD: same reason, just passing it as a "this" pointer
g_p->func();
}

那么这也是糟糕的代码:

void also_bad_code(bool maybe)
{
const auto& maybe_g_p_alias = maybe ? g_p : someOtherValue; // Potentially aliases g_p
f(*maybe_g_p_alias);
maybe_g_p_alias->func();
}

在这种情况下,"别名"的意思是"同一对象的另一个名称"。

f将引用widget& w作为参数。因此,如果您用f(g_p)调用它,那么f内部g_pw都引用同一个对象g_pwg_p的别名。指南说你不应该调用f(g_p)(g_p是一个全局对象(,也不应该调用f(w)(w 是全局对象的别名本地/本地别名(。