扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇内容主要讲解“C++为什么原始指针不应拥有所有权”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++为什么原始指针不应拥有所有权”吧!
10年积累的网站建设、成都网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有临颍免费网站建设让你可以放心的选择与我们合作。
R.3: 原始指针(T*)不应拥有所有权
这一点不存在任何例外(无论是C++标准还是大部分代码)而且大多数原始指针就是没有所有权的。我们需要所有权指针被定义出来,这样就可以可靠地,高效地删除所有权指针指向的对象。
Example(示例)
void f()
{
int* p1 = new int{7}; // bad: raw owning pointer
auto p2 = make_unique(7); // OK: the int is owned by a unique pointer
// ...
}
unique_ptr通过(即使在发生异常的情况下)保证对象的删除来防止内存泄露。而T*不会。
Example(示例)
template
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
class X2 {
public:
owner p; // OK: p is owning
T* q; // OK: q is not owning
// ...
};
例外主要来源于既有代码,特别是那些由于ABIs必须保持C兼容性或者包含C或C风格C++接口的情况。事实上存在成百万行的代码违反这条反对T*持有所有权的准则,它们不能被忽略。我们很高兴地看到软件工具可以将20年以上的老代码转换为崭新的现代C++代码,我们鼓励这类工具的开发、部署和使用,我们甚至向这个领域的研究做出了贡献,而且将继续做出贡献。然而这需要时间:“既有代码”的产生快于我们翻新旧代码的速度,因此这个过程将会持续一些年。
不可能所有的代码都被重写(即使存在优秀的转换软件),很快重写更不可能。这个问题不可能通过将所有具有所有权指针转换为unique_ptr和shared_ptr来解决,一部分的原因是基础的资源持有者需要/使用具有所有权的原始指针(同时也是简单指针)。例如,普通的vector实现包含一个所有权指针和两个非所有权指针。很多ABI(本质上讲所有面向C语言的接口)使用T*,其中有些具有所有权。因为需要维持C语言可编译,因此有些接口不能简单地加注所有权(虽然这是很少见的宏的好用法,它只是在C++模式时展开成为所有权指针)。
Note(注意)
owner
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(注意)
如果需要指针语义(例如因为返回的指针需要指向类层次中的基类(某个接口)),返回一个智能指针。
Enforcement(实施建议)
(Simple) Warn on delete of a raw pointer that is not an owner
(简单)警告销毁owner
(Moderate) Warn on failure to either reset or explicitly delete an owner
(中等)如果没有在所有代码路径上重置或者销毁onwer
(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++为什么原始指针不应拥有所有权”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流