这个例子中的 'aliased local shared_ptr' 是什么
What is an 'aliased local shared_ptr' in this example
我对 Cpp 核心指南中的示例有疑问。在 R.37: Do not pass a pointer or reference obtained from an aliased smart pointer 中有以下示例:
// 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
}
而且我不明白第一条评论中的 'aliased local' 是什么意思。它是否连接到像
这样的别名指针类型
using WidgetPtr = std::shared_ptr<widget>;
还是我完全走错了路?我想我理解这个示例是针对全局 shared_ptr,但不是针对别名本地。
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();
}
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。
"alias" 在这种情况下表示 "another name for the same object".
f
将引用 widget& w
作为参数。因此,如果您使用 f(g_p)
调用它,那么在 f
中, g_p
和 w
都引用同一个对象 g_p
。 w
是 g_p
的别名。指南说你不应该调用 f(g_p)
(g_p 是一个全局对象)你也不应该调用 f(w)
(w 是一个别名 local/a 局部别名到全局对象)。
我对 Cpp 核心指南中的示例有疑问。在 R.37: Do not pass a pointer or reference obtained from an aliased smart pointer 中有以下示例:
// 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
}
而且我不明白第一条评论中的 'aliased local' 是什么意思。它是否连接到像
这样的别名指针类型using WidgetPtr = std::shared_ptr<widget>;
还是我完全走错了路?我想我理解这个示例是针对全局 shared_ptr,但不是针对别名本地。
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();
}
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。
"alias" 在这种情况下表示 "another name for the same object".
f
将引用 widget& w
作为参数。因此,如果您使用 f(g_p)
调用它,那么在 f
中, g_p
和 w
都引用同一个对象 g_p
。 w
是 g_p
的别名。指南说你不应该调用 f(g_p)
(g_p 是一个全局对象)你也不应该调用 f(w)
(w 是一个别名 local/a 局部别名到全局对象)。