在此示例中,什么是“别名本地shared_ptr”

时间:2019-08-29 16:17:29

标签: c++ alias smart-pointers cpp-core-guidelines

我对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理解了这个示例,但对于别名本地不理解。

3 个答案:

答案 0 :(得分:3)

std::shared_ptr会自动销毁指向该对象的所有std::shared_ptr或将其重新分配给其他对象。

这意味着,如果您存储由std::shared_ptr管理的对象的指针或引用(这是 aliased 指针),如果{{1 }}管理它已被破坏或修改。

您忽略了示例中最重要的部分,但是在这种情况下:

std::shared_ptr

std::shared_ptr<int> shared = std::make_shared<int>(7); int& ptr = *shared; shared = nullptr; 设置为shared时,指向的对象将立即被销毁,这意味着指向它的任何指针(如nullptr)现在都悬空了,并且正在读取或写入会导致UB。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

在这种情况下,“别名”表示“同一对象的另一个名称”。

f以引用widget& w作为参数。因此,如果您用f(g_p)进行调用,则在fg_p内都引用同一对象wg_pw的别名。准则规定,您不应调用g_p(g_p是全局对象),也不应调用f(g_p)(w是别名的本地对象/全局对象的本地别名)。