假设我们有一个如下所示的类。
class DoStuffWithRef
{
DoStuffWithRef(LargeObject& lo) : lo_(lo) {}
// a bunch of member functions, some of them useful
// [...]
private:
LargeObject& lo_;
};
该类的设计使得唯一合理的用途是当至少一个其他实体拥有所lo_
引用对象的所有权时。如果客户端代码适当地使用该类,则无需DoStuffWithRef
拥有LargeObject
.
如果类被滥用,有没有办法强制执行这种用法或发出错误信号?除了记录DoStuffWithRef
?
例如,自动存储DoStuffWithRef
可能指的是自动存储LargeObject
。
void foo()
{
LargeObject lo;
DoStuffWithRef dswr(lo);
// some code that makes use of the DoStuffWithRef instance
return;
}
这是我想到的主要用途,尽管在其他可能的情况下可以保证其他人拥有所有权。
问题是客户端代码很可能会创建一个DoStuffWithRef
以悬空引用结束的实例。如果没有其他人拥有 aLargeObject
所指的 a 的所有权,那么当试图访问DoStuffWithRef
时就会出现混乱。更糟糕的是,只有在犯错很久之后才会出现混乱。DoStuffWithRef
LargeObject
过去出现这种情况时,我使用 aboost::shared_ptr<>
而不是引用(这是在 C++03 中)。这并不能恰当地表达类的语义。前提是DoStuffWithRef
不需要所有权——它的目的是作用于他人拥有的对象,如果没有其他人拥有该对象,那么提供的功能DoStuffWithRef
就没有意义了。授予所有权DoStuffWithRef
具有不必要的开销并强制共享所有权语义。weak_ptr<>
也会有错误的语义,因为我们不应该在运行时询问指针是否有效。
我从来没有在代码的性能敏感部分或共享所有权是一个重大负担的情况下出现这种情况,所以它并不重要,但我希望我知道一种在 C++ 中准确表达这一点的方法。成本很小,但它们也是不必要的。更重要的是,ashared_ptr<>
会隐藏对类的不正确使用。如果DoStuffWithRef
修改为使用 a 的 ashared_ptr<>
是 a 的唯一剩余所有者LargeObject
,则在短期内避免了悬空引用,但客户端代码最终处于未知领域。