Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 强制安全使用包含引用或原始指针的类_C++_Smart Pointers_Ownership_Data Members - Fatal编程技术网

C++ 强制安全使用包含引用或原始指针的类

C++ 强制安全使用包含引用或原始指针的类,c++,smart-pointers,ownership,data-members,C++,Smart Pointers,Ownership,Data Members,假设我们有一个如下所示的类 class DoStuffWithRef { DoStuffWithRef(LargeObject& lo) : lo_(lo) {} // a bunch of member functions, some of them useful // [...] private: LargeObject& lo_; }; 该类的设计使得唯一合理的使用是当至少有一个其他实体拥有lo\ucode>引用的对象的所有权时。如果客

假设我们有一个如下所示的类

class DoStuffWithRef
{
    DoStuffWithRef(LargeObject& lo) : lo_(lo) {}

    // a bunch of member functions, some of them useful
    // [...]

private:
    LargeObject& lo_;
};
该类的设计使得唯一合理的使用是当至少有一个其他实体拥有
lo\ucode>引用的对象的所有权时。如果客户机代码正确地使用了该类,则不需要
dostufwithref
拥有
LargeObject
的所有权

void foo()
{
    LargeObject lo;
    DoStuffWithRef dswr(lo);
    // some code that makes use of the DoStuffWithRef instance
    return;
}
如果类被误用,有没有办法强制执行这种用法或发出错误信号?除了记录
dostufwithref
的预期用途外,还能做些什么

例如,自动存储的
dostufwithref
可能指的是自动存储的
LargeObject

void foo()
{
    LargeObject lo;
    DoStuffWithRef dswr(lo);
    // some code that makes use of the DoStuffWithRef instance
    return;
}
这是我想到的主要用法,尽管在其他可能的情况下,可能会保证其他人拥有所有权

问题是,客户端代码很可能创建一个
dostufwithref
实例,该实例将以一个悬空引用结束。如果没有其他人拥有由
dostufwithref
引用的
LargeObject
的所有权,那么当
dostufwithref
试图访问
LargeObject
时,就会出现混乱。更糟糕的是,只有在错误发生后很长一段时间才会出现混乱

当这在过去出现时,我使用了
boost::shared_ptr
而不是引用(这是在C++03中)。这并不能很好地表达类的语义。前提是,
dostufwithref
不需要所有权——它意味着作用于其他人拥有的对象,如果没有其他人拥有该对象,那么
dostufwithref
提供的功能就毫无意义。将所有权赋予
dostufwithref
会产生不必要的开销,并强制共享所有权语义<代码>弱\u ptr
也会有错误的语义,因为我们不应该在运行时询问指针是否有效


我从来没有在一个性能敏感的代码段出现这种情况,或者在共享所有权是一个重大负担的情况下,所以它并没有真正重要,但我希望我知道一种在C++中准确地表达这一点的方法。成本很小,但也没有必要。更重要的是,
shared\u ptr
将隐藏类的错误使用。如果修改为使用
共享的
dostufwithref
,是
大型对象
的唯一剩余所有者,则在短期内避免了悬空引用,但客户端代码最终位于未知区域。

dostufwithref是否有其他状态?如果不是,它似乎是一个实用功能桶。对LargeObject的引用也可以作为参数传递给每个函数。这也解决了所有权问题


否则,如果它是有状态的,这显然是共享所有权的情况,因为dostufwithref确实需要将大型对象的单个活动实例的生存期延长到其自身的生存期。或者,使用弱指针并吃掉运行时检查的成本…

,这将包含在c++17中。它可能是一个函数对象,它使用数据成员作为“函数参数”。它可以说有状态,但肯定不会有可变状态。使用函数对象而不是函数的原因可能是我们希望将其参数化,然后使用它创建其他函数对象。确定。对我来说,你提到的函数对象实际上意味着它应该是一个共享指针。由于您正在传递捕获的原始引用,这本身就很危险。我的意思是,特别是如果您开始编写函数对象等,很快您就会在另一个线程等上使用它。这样会带来痛苦,除非您对所有权要求严格。:)如果我们坚持客户机代码不受限制地使用函数对象,那么您的观点是正确的,但是如果我们只打算在同一范围内创建和使用函数对象呢?好吧。。我看不出它是如何静态强制执行的。例如,std::function使用类型擦除,这可能会造成妨碍。如果这个对象要在有限的上下文中使用,我可能会将它粘贴在“details”子命名空间中,并将其称为实现细节。也就是说,除了确保它不是“公开的”之外,不要担心它。