0

有没有办法防止一个特定对象在另一个对象仍然存在时被销毁,而无需明确地让第二个对象的类知道第一个对象?

这是一个例子:

class A { /* A creates B*/ };
class B {};

int main() {
    auto spA = std::make_shared<A>();
    auto spB = spA->getB();

    spA.reset();
    spB->DoSomething(); 
}

之后spA.reset(),我希望至少有一个对指向的对象的引用spA。或者,换句话说:我spA只想在调用spB->DoSomething().

但是,一个重要的先决条件是B不允许“知道”的A(例如,不允许持有指向它的指针/引用)。

据我了解,共享指针提供了一些可以帮助解决此问题的功能,但我不确定是哪一个。

编辑:

A的简要结构B如下:

class A 
{
public:
    A() 
    { 
        m_B = B::FactoryB(); 
    }
    std::shared_ptr<B> getB()
    {
        return m_B;
    }
private:
    std::shared_ptr<B> m_B; 
};

class B 
{
public:
    static std::shared_ptr FactoryB()
    {
        return std::make_shared<B>();
    }
};

EDIT2(我的解决方案):

因此,使用@MSalters 提供的建议,我能够找到适合我的解决方案。在这种情况下,它比预期的要简单得多,因此我只需要调整A::getB()

    std::shared_ptr<B> getB()
    {
        std::shared<B> spBAlias(this->shared_from_this(), m_B.get());
        return spBAlias;
    }

m_B在这里,不仅仅是返回,而是创建并返回一个类型A::getB()的共享指针(使用别名构造函数),这会影响对象的引用计数(由 提供)。因此,调用从二到一的使用减少,使调用成为可能。要使用,需要继承自:spBAliasBAthis->shared_from_this()spA.reset()mainspAspB->DoSomething()shared_from_this()Astd::enable_shared_from_this<A>

class A : public std::enable_shared_from_this<A> { /* ... */ }
4

2 回答 2

3

您完全可以使用 来执行此操作shared_ptr,但您必须编写一些额外的代码。

只需使用自定义删除器getB返回 a shared_ptr<B>...删除器应该是一个按值捕获 a 的 lambda ,并且只有在超出范围并尝试删除对象时才shared_ptr<A>显式释放它。spBB

A将不得不派生从std::enable_shared_from_this内部获得一个可行的共享指针到自身A::getB()

如果B对象实际上是 的子对象A,那么这就足够了。否则,您也应该真正删除B


int main() {
    shared_ptr<A> spA = std::make_shared<A>();
    shared_ptr<B> spB = spA->getB();

    spA.reset();         // spB's deleter keeps the refcount nonzero
    spB->DoSomething();  // fine
}                        // spB's destructor finally deletes *spA
于 2021-05-04T12:45:10.747 回答
2

shared_ptr有一个叫做别名构造函数的东西。Ashared_ptr<B>可以从 ashared_ptr<A>和 a创建B*。this 的析构函数shared_ptr<B>将删除A对象,而不是B.

在您的情况下,您的A对象本身可以包含一个unique_ptr<B>,甚至是一个直接B成员。

于 2021-05-04T13:45:39.677 回答