可以保存对shared_ptr管理的对象的引用吗?

Is it OK to save a reference to the object managed by a shared_ptr?

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

#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)

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

这样就好了:

#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.
  3. 之前在运行时检查有效性

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