【发布时间】:2013-08-30 05:48:44
【问题描述】:
所以,我已经完成了(少量)reading,并且知道unique_ptr 与原始指针结合使用是建模唯一所有权时使用的模式。
但是,我真的很喜欢使用 weak_ptr 来检查一个值是否有效,然后在使用后丢弃 shared_ptr 的简单明了的概念,这让每个人都很高兴(以轻微的引用计数性能成本为代价)。
我现在的特殊问题是创建一个富有表现力和灵活的系统来跟踪多点触摸点,使用代表触摸的对象的破坏作为触摸已经结束的信号似乎很优雅。如果我使用原始指针路由,我需要定义与该系统接口的每个组件都需要遵守的一些语义,这有点难看,比如涉及第二个参数,指示指针是否有效等。 原始指针路由的这个问题可能是一个稻草人问题,因为我不认为这会成为一个大型项目,但这个问题主要是关于如何编写最好的现代 C++ 代码。
伪代码:
class InputConsumer {
void handle(std::list<std::weak_ptr<Touch>>*);
// consumer doesnt hold references to anything outside of its concern.
// It only has to know how to deal with input data made available to it.
// the consumer is a child who is given toys to play with and I am trying to
// see how far I can go to sandbox it
}
class InputSender {
std::list<std::weak_ptr<Touch>> exposedinputdata;
std::list<std::shared_ptr<Touch>> therealownedtouches;
// sender populates exposedinputdata when input events come in.
// I want to let the consumer copy out weak_ptrs as much as it wants,
// but for it to never hold on to it indefinitely. There does not appear
// to be an easy way to enforce this (admittedly it is kind of vague. it
// has to be around for long enough to be used to read out data, but
// not e.g. 3 frames. Maybe what I need is to make an intelligent
// smart pointer that has a timer inside of it.)
std::list<std::weak_ptr<InputConsumer>> consumers;
void feedConsumersWithInput() {
for (auto i = consumers.begin(); i != consumers.end(); ++i) {
if (i->expired()) {
consumers.erase(i);
} else {
i->lock()->handle(&exposedinputdata);
}
}
}
当我看到weak_ptr 能够表达与我正在建模的语义非常相似的语义时,我真的很想使用它,因为它的界面简洁明了,最重要的是它自我记录了这段代码是怎样的去上班。这是一个巨大的好处。
现在我很确定在InputConsumer 在weak_ptr<Touch> 上调用lock() 并保留shared_ptr<Touch> 之前,一切都会非常顺利。即使在它的主要所有者删除了其拥有的shared_ptr 之后,它也会阻止底层Touch 被释放!在我看来,这似乎是唯一的皱纹,而且还有一点点。我认为用 shared_ptr 搞砸所有权处理要比用原始指针搞砸要难得多。
有什么方法可以解决这个问题?我正在考虑创建一个weak_ptr的模板子类(?!我从来没有写过这样的东西,最近进入了模板。爱他们)以某种方式禁止保留shared_ptr或其他东西。
也许我可以继承 shared_ptr 并覆盖它的 dtor 以抛出,如果它不调用删除器?
【问题讨论】:
-
您可以轻松检查
unique_ptr是否包含有效指针:en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool -
好吧,我不会检查 unique_ptr。系统的设计是这样的,它应该支持拥有 smartptr 的状态对正在执行检查的事物不可用。这就是为什么 weak_ptrs 这么好。我可以把它们像糖果一样传来传去,只要没有人去用糖果做不圣洁的事情,派对就会继续。不要没有人必须四处监视所有的人。 (糖果是在超空间中连接在一起的魔法信标)
-
你说的
lock()是什么?为什么调用它会阻止shared_ptr删除其拥有的资源(假设引用计数为零)? -
有没有可能用一点伪代码来表达你的对象模型?我想你可能有一些错误的前提。通常,您可以在所有者对象中使用
unique_ptr成员和供其他人使用的原始指针。您只需要小心原始指针的生命周期嵌套在所有者对象的生命周期内。
标签: c++ pointers c++11 smart-pointers weak-references