所以,我已经完成了(少量)阅读,并且知道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
并保留. 即使在它的主要所有者已经删除了它的所有权之后,它也会阻止底层资产被释放!在我看来,这似乎是唯一的皱纹,而且还有一点点。我认为用 shared_ptr 搞砸所有权处理要比用原始指针搞砸要难得多。lock()
weak_ptr<Touch>
shared_ptr<Touch>
Touch
shared_ptr
有什么方法可以解决这个问题?我正在考虑制作一个weak_ptr的模板子类(?!我从来没有写过这样的东西,最近进入了模板。爱他们)会以某种方式禁止保留shared_ptr或其他东西。
如果它不调用删除器,也许我可以shared_ptr
继承并覆盖它的 dtor 来抛出?