Que*_*tin 12 c++ shared-ptr ownership language-lawyer
我正在考虑使用"自杀对象"来模拟游戏中的实体,即能够自行删除的对象.现在,一般的C++ 03的实现(普通旧delete this)不执行任何潜在指的自杀的对象,这就是为什么我使用的其他对象std::shared_ptr和std::weak_ptr.
现在进行代码转储:
#include <memory>
#include <iostream>
#include <cassert>
struct SuObj {
SuObj() { std::cout << __func__ << '\n'; }
~SuObj() { std::cout << __func__ << '\n'; }
void die() {
ptr.reset();
}
static std::weak_ptr<SuObj> create() {
std::shared_ptr<SuObj> obj = std::make_shared<SuObj>();
return (obj->ptr = std::move(obj));
}
private:
std::shared_ptr<SuObj> ptr;
};
int main() {
std::weak_ptr<SuObj> obj = SuObj::create();
assert(!obj.expired());
std::cout << "Still alive\n";
obj.lock()->die();
assert(obj.expired());
std::cout << "Deleted\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码似乎工作正常.但是,我想让别人去关注它.这段代码有意义吗?我是否盲目地驶入未定义的土地?我应该放弃键盘并立即开始艺术研究吗?
我希望这个问题能够充分缩小.看起来有点微小而且低级别的CR.
我不打算在多线程代码中使用它.如果有需要,我一定会重新考虑整件事.
当你有shared_ptr基于对象的生命周期时,你的对象的生命周期就是共同拥有它的对象的联合的“生命周期” shared_ptr。
就您而言,您有一个内部shared_ptr,并且您的对象在该内部过期之前不会消亡shared_ptr。
然而,这并不意味着您可以自杀。如果删除最后一个引用,并且任何人都已存储结果,则.lock()您weak_ptr的对象将继续存在。由于这是从外部访问该对象的唯一方法,因此可能会发生这种情况1。
简而言之,die()无法杀死对象。最好将其称为remove_life_support(),因为在所述生命维持装置被移除后,其他东西可以使物体保持活力。
除此之外,你的设计有效。
1
你可以说“好吧,那么调用者不应该保留shared_ptr周围”——但这不起作用,因为对象是否有效的检查只有在对象shared_ptr持续存在时才有效。另外,通过公开 create 的方式shared_ptr,您无法保证客户端代码不会存储它们(意外或故意)。
如果您想要严重偏执的稳健性,基于事务的模型(您传入 lambda,并在内部对其进行操作)可以帮助解决此问题。
或者你可以和这个物体一起生活,有时会生活得太久。
考虑将这些混乱的细节隐藏在常规类型(或几乎常规)后面,这会带来pImpl令人讨厌的内存管理问题。这pImpl可能是weak_ptr具有上述语义的 a 。
然后代码的用户只需要与常规(或伪常规)包装器交互。
如果您不希望克隆变得容易,请禁用复制构造/分配并仅公开移动。
现在你讨厌的内存管理隐藏在外观后面,如果你决定你做错了,外部的pseudoRegular接口可能有不同的内容。
| 归档时间: |
|
| 查看次数: |
342 次 |
| 最近记录: |