只要另一个对象存在,如何让一个对象保持活动状态?
How to keep one object alive as long as another object exists?
有没有一种方法可以防止一个特定对象在另一个对象仍然存在的情况下被销毁,无需明确地让第二个对象的class知道第一个?
这是一个例子:
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
指向的对象的引用。或者,换句话说:我只想在调用 spB->DoSomething()
.
之后销毁 spA
指向的对象
但是,一个重要的先决条件是 B
不允许“知道”A
(例如,不允许对其持有 pointer/reference)。
据我所知,共享指针提供了一些功能可以帮助解决这个问题,但我不确定是哪一个。
编辑:
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;
}
在这里,A::getB()
不是仅仅返回 m_B
,而是创建和 returns 类型为 B
的共享指针 spBAlias
(使用别名构造函数),这会影响 A
对象(由 this->shared_from_this()
提供)的引用计数。因此,在 main
中调用 spA.reset()
会将 spA
的使用次数从两次减少到一次,从而使 spB->DoSomething()
的调用成为可能。要使用shared_from_this()
,A
需要继承自std::enable_shared_from_this<A>
:
class A : public std::enable_shared_from_this<A> { /* ... */ }
您完全可以使用 shared_ptr
执行此操作,但您必须编写一些额外的代码。
只需要 getB
return 一个带有自定义删除器的 shared_ptr<B>
...删除器应该是一个 lambda 按值捕获 shared_ptr<A>
,并显式释放 that 仅当 spB
超出范围并尝试删除 B
对象时。
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
shared_ptr
有一个叫做 别名构造函数 的东西。可以从 shared_ptr<A>
和 B*
创建 shared_ptr<B>
。此 shared_ptr<B>
的析构函数将删除 A
对象,而不是 B
.
在你的例子中,你的 A
对象本身可以包含一个 unique_ptr<B>
,甚至是一个直接的 B
成员。
有没有一种方法可以防止一个特定对象在另一个对象仍然存在的情况下被销毁,无需明确地让第二个对象的class知道第一个?
这是一个例子:
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
指向的对象的引用。或者,换句话说:我只想在调用 spB->DoSomething()
.
spA
指向的对象
但是,一个重要的先决条件是 B
不允许“知道”A
(例如,不允许对其持有 pointer/reference)。
据我所知,共享指针提供了一些功能可以帮助解决这个问题,但我不确定是哪一个。
编辑:
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;
}
在这里,A::getB()
不是仅仅返回 m_B
,而是创建和 returns 类型为 B
的共享指针 spBAlias
(使用别名构造函数),这会影响 A
对象(由 this->shared_from_this()
提供)的引用计数。因此,在 main
中调用 spA.reset()
会将 spA
的使用次数从两次减少到一次,从而使 spB->DoSomething()
的调用成为可能。要使用shared_from_this()
,A
需要继承自std::enable_shared_from_this<A>
:
class A : public std::enable_shared_from_this<A> { /* ... */ }
您完全可以使用 shared_ptr
执行此操作,但您必须编写一些额外的代码。
只需要 getB
return 一个带有自定义删除器的 shared_ptr<B>
...删除器应该是一个 lambda 按值捕获 shared_ptr<A>
,并显式释放 that 仅当 spB
超出范围并尝试删除 B
对象时。
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
shared_ptr
有一个叫做 别名构造函数 的东西。可以从 shared_ptr<A>
和 B*
创建 shared_ptr<B>
。此 shared_ptr<B>
的析构函数将删除 A
对象,而不是 B
.
在你的例子中,你的 A
对象本身可以包含一个 unique_ptr<B>
,甚至是一个直接的 B
成员。