c++ - 只要另一个对象存在,如何使一个对象保持活动状态?
问题描述
有没有办法防止一个特定对象在另一个对象仍然存在时被销毁,而无需明确地让第二个对象的类知道第一个对象?
这是一个例子:
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()
的共享指针(使用别名构造函数),这会影响对象的引用计数(由 提供)。因此,调用从二到一的使用减少,使调用成为可能。要使用,需要继承自:spBAlias
B
A
this->shared_from_this()
spA.reset()
main
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
返回 a shared_ptr<B>
...删除器应该是一个按值捕获 a 的 lambda ,并且只有在超出范围并尝试删除对象时才shared_ptr<A>
显式释放它。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
推荐阅读
- python - 如果作为 systemd 服务运行,则显示 python 脚本进度条
- git - sonarqube - 添加自签名证书以连接 git
- c - 如果指针在赋值给它的内存位置后增加会发生什么?
- javascript - 在数据表变量中转义单引号
- swift - 对象已被删除或失效 - 仅在删除对象的设备上抛出错误
- unity3d - Hololens:如何调整光标指针灵敏度
- html - 启动对象从随机点沿 SVG 路径移动
- html - CodeSanbox 单独下载选项?
- python - Tkinter 滚动条不起作用。我究竟做错了什么?
- swagger-2.0 - 从 Springfox Swagger 2 迁移到 Springdoc Open API