温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C++为什么原始指针不应拥有所有权

发布时间:2021-11-26 15:19:29 来源:亿速云 阅读:152 作者:iii 栏目:大数据

本篇内容主要讲解“C++为什么原始指针不应拥有所有权”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++为什么原始指针不应拥有所有权”吧!

R.3: 原始指针(T*)不应拥有所有权

Reason(原因)

这一点不存在任何例外(无论是C++标准还是大部分代码)而且大多数原始指针就是没有所有权的。我们需要所有权指针被定义出来,这样就可以可靠地,高效地删除所有权指针指向的对象。

Example(示例)

void f()
{
   int* p1 = new int{7};           // bad: raw owning pointer
   auto p2 = make_unique<int>(7);  // OK: the int is owned by a unique pointer
   // ...
}

unique_ptr通过(即使在发生异常的情况下)保证对象的删除来防止内存泄露。而T*不会。

Example(示例)

template<typename T>
class X {
public:
   T* p;   // bad: it is unclear whether p is owning or not
   T* q;   // bad: it is unclear whether q is owning or not
   // ...
};

我们可以通过明确地赋予所有权来解决这个问题。

template<typename T>
class X2 {
public:
   owner<T*> p;  // OK: p is owning
   T* q;         // OK: q is not owning
   // ...
};
Exception(例外)

例外主要来源于既有代码,特别是那些由于ABIs必须保持C兼容性或者包含C或C风格C++接口的情况。事实上存在成百万行的代码违反这条反对T*持有所有权的准则,它们不能被忽略。我们很高兴地看到软件工具可以将20年以上的老代码转换为崭新的现代C++代码,我们鼓励这类工具的开发、部署和使用,我们甚至向这个领域的研究做出了贡献,而且将继续做出贡献。然而这需要时间:“既有代码”的产生快于我们翻新旧代码的速度,因此这个过程将会持续一些年。

不可能所有的代码都被重写(即使存在优秀的转换软件),很快重写更不可能。这个问题不可能通过将所有具有所有权指针转换为unique_ptr和shared_ptr来解决,一部分的原因是基础的资源持有者需要/使用具有所有权的原始指针(同时也是简单指针)。例如,普通的vector实现包含一个所有权指针和两个非所有权指针。很多ABI(本质上讲所有面向C语言的接口)使用T*,其中有些具有所有权。因为需要维持C语言可编译,因此有些接口不能简单地加注所有权(虽然这是很少见的宏的好用法,它只是在C++模式时展开成为所有权指针)。

Note(注意)

owner<T*>没有包含任何超过T*的语义。它不修改任何代码就可以使用而且不会影响ABI。它只是面向程序员和分析工具的一个指示信息。例如,如果owner<T*>是某类的成员,那个最好准备一个析构函数来销毁它。

Example, bad(反面示例)

返回一个(原始)指针会增加调用者生命周期管理的不确定性;即:谁应该销毁指针指向的对象?

Gadget* make_gadget(int n)
{
   auto p = new Gadget{n};
   // ...
   return p;
}

void caller(int n)
{
   auto p = make_gadget(n);   // remember to delete p
   // ...
   delete p;
}

这段代码可以排除来自内存泄漏问题的痛苦,但是增加了虚假的分配和释放操作和没有必要的冗长性。如果Gadget很容易移出函数(也就是说,很小或者存在高效的移动操作),直接只用传值(参照“输出“返回值)。

Gadget make_gadget(int n)
{
   Gadget g{n};
   // ...
   return g;
}
Note(注意)

这条准则适用于工厂函数。

Note(注意)

如果需要指针语义(例如因为返回的指针需要指向类层次中的基类(某个接口)),返回一个智能指针。

Enforcement(实施建议)

  • (Simple) Warn on delete of a raw pointer that is not an owner<T>.

  • (简单)警告销毁owner<T>类型之外的原始指针的情况。

  • (Moderate) Warn on failure to either reset or explicitly delete an owner<T> pointer on every code path.

  • (中等)如果没有在所有代码路径上重置或者销毁onwer<T>指针,发出警告。

  • (Simple) Warn if the return value of new is assigned to a raw pointer.

  • (简单)如果new的返回值赋给原始指针,发出警告。

  • (Simple) Warn if a function returns an object that was allocated within the function but has a move constructor. Suggest considering returning it by value instead.、

  • (简单)如果一个函数返回的对象在函数内分配内存,但是包含移动构造函数。提出建议通过传值方式返回。

到此,相信大家对“C++为什么原始指针不应拥有所有权”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++
AI