【问题标题】:Is it OK to save a reference to the object managed by a shared_ptr?保存对由 shared_ptr 管理的对象的引用是否可以?
【发布时间】:2021-03-23 20:21:14
【问题描述】:

这是我正在做的工作版本。

#include <memory>

using namespace std;

struct thing {
    int blah;
};

struct parentObj {
    parentObj(thing & incomingThing) : isThisOK(incomingThing) {};
    thing & isThisOK;
};

int main()
{
    shared_ptr<thing> thingInstance = make_shared<thing>();
    shared_ptr<parentObj> theObj = make_shared<parentObj>(*thingInstance);
}

我喜欢将共享指针分配给它的类型的引用。 (ctrl+f isThisOK)

这里有意想不到的后果吗?我应该使用弱指针吗?

【问题讨论】:

  • 这就像保存对任何其他对象的引用一样好。这意味着,编译器不会为您捕获对象生命周期错误,这个负担就在您的肩上。
  • 它可以编译,但我不确定这是shared_ptr 的最佳用途。 parentObjthing&amp; 的引用不允许它知道何时访问它是有效的。您可能根本不使用shared_ptr
  • 一个大问题是,一旦theObj 的引用为零,它就会破坏其底层对象,thingInstance 即使不再存在,它仍将指向它。
  • @sanitizedUser 错误,默认销毁不销毁引用数据成员。
  • 这段代码没问题,但我想你的实际代码更复杂——你必须保证一旦thingInstance被销毁,那么Obj就不会使用它的引用(否则你会得到UB)。您可以将 std::weak_ptr 传递给 parentObj 以防止 UB

标签: c++ shared-ptr smart-pointers


【解决方案1】:

这样就好了:

#include <memory>

using namespace std;

struct thing {
    int blah;
};

struct parentObj {
    parentObj(thing& incomingThing) : isThisOK(incomingThing) {};
    thing& isThisOK;
};

int main()
{
    thing thingInstance;
    shared_ptr<parentObj> theObj = make_shared<parentObj>(thingInstance);
}

就像函数参数默认情况下应该与所有权策略无关,除非需要,我会说你所做的是正确的,甚至在特定情况下推荐它。如果除非需要,否则您的对象不知道所有权策略,这通常是可行的方法。

请注意两件事:

  1. parentObj 应被视为无效时,您必须小心自己的生命并设置界限。
  2. 请注意,当您改用std::unique_ptr 时,执行类似代码的操作要容易得多,因为唯一指针的所有者更容易跟踪。在读取具有唯一指针的代码时,您可以轻松地发现生命周期应该在哪里结束以及它在哪里传输。有一个共享的,不太清楚。使用唯一指针,您可以“静态”设置边界,例如,parentObjthing 死亡后无效,并且应该清楚两者的生命周期何时结束。如果您有共享指针,我建议您在使用 parentObj 之前有办法在运行时检查有效性。

只有在设计上parentObj 应该在运行时检查thing 的有效性,并且parentObj 的用户无法检查thing 的有效性时,我才会使用std::weak_ptr。通常,代码中有一个位置可以确定thingparentObj 何时开始和结束它们的生命周期。如果你有一个地方知道它们的生命周期,那么我会说代码有责任检查thingparentObj 的有效性,并让这两种类型更简单。

【讨论】:

    猜你喜欢
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    相关资源
    最近更新 更多