是否可以将唯一指针指向共享指针?

Is it ok practice to have a unique pointer pointed at a shared pointer?

本文关键字:指针 共享 唯一 是否      更新时间:2023-10-16

我在尝试解决C++中的指针问题时遇到了一些困难。

假设我有一个名为MyClass的类。在此类中,有一个共享指针指向某个称为MyResource的外部资源。现在我们再说,在MyClass中,有几个对象叫做MyObject的实例。MyObject的每个实例还需要引用MyResource。假设这个类除了包含我刚刚提到的这些组件之外什么都不做

class MyClass
{
shared_ptr<MyResource> m_p_my_resource;
MyObject m_my_object1;
MyObject m_my_object2;
MyObject m_my_object3;
}

我以前(尝试)如何实现这一点,我将创建一个共享指针并将其提供给m_p_my_resource.然后我会给每个MyObject实例m_p_my_resource.我假设每当m_p_my_resource更改为指向新MyResource时,MyObject中的每一个也会指向新资源。

但是,我意识到我所做的是不正确的。当我改变m_p_my_resource时,这确实指向一个新的资源。但是,MyObject的每个实例仍将指向原始MyResource

现在,我正在尝试思考如何实际实现我最初尝试做的事情的方法:能够更改m_p_my_resource并让每个实例也指向新资源。

解决此问题的一种方法是在m_p_my_resource更改时更新每个MyObject实例。我可能需要一个setResource方法来更新m_p_my_resource,然后遍历MyObject的每个实例。

另一种解决方案是让MyObject的每个实例都包含一个指向MyResource指针的指针。因此,如果每个MyObject都指向指向资源的指针而不是资源本身,我可以更改m_p_my_resource,并且每个对象也能够确定新资源。

虽然第二种方法可能在我上面列出的类示例中有效,但对于类中未包含的MyObject实例来说,它并不优雅。例如,如果我只是在堆栈上创建了一个MyObject,我宁愿让它直接指向资源,而不是让它指向指向资源的某个中间指针......

所以我正在尝试确定实现我所描述的内容的最佳方法。我对智能指针仍然相对较新,并且很好奇我试图做的是否愚蠢,或者是否有更好/明显的替代解决方案。

如果MyObject的生存期确实与MyClass的生存期相同,那么MyObject的每个实例都可以保留指向shared_ptr<...>的引用或指针来实现您想要的。

class MyClass {
public:
shared_ptr<MyResource> resource;
MyObject obj1 { resource };
MyObject obj2 { resource };
};
class MyObject {
public:
shared_ptr<MyResource>& resource;
void foo() {
resource->do_something(); // works transparently
}
}

您可以安全地更改MyClass::resource的内容:

void bar(MyClass& myClass) {
myClass.resource.reset(new MyResource());
assert(myClass.resource.get() == myClass.ob1.resource.get());
assert(myClass.resource.get() == myClass.ob1.resource.get());
}

双指针是解决问题的正确技术。

但是,我有点困惑,为什么您会像您在标题中所说的那样unique_ptrshared_ptr。你没有在问题的任何地方提到unique_ptr,似乎你真正想要的是一个shared_ptr<unique_ptr<MyResource>>,而不是一个unique_ptr<shared_ptr<MyResource>>