一,构造函数与析构函数
auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:
int* p = new int(0);
auto_ptr<int> ap(p);
从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。
这里我们有几点要注意:
1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:
int* p = new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p);
因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr.
2)
不应该用auto_ptr来管理一个数组指针:
int* pa = new int[10];
auto_ptr<int> ap(pa);
因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。
3) 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。
4) 因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:
~auto_ptr() throw()
{
if(ap)
delete ap;
}
二,拷贝构造与赋值
与引用计数型智能指针不同的,auto_ptr要求其对“裸”指针的完全占有性。也就是说一个”裸“指针不能同时被两个以上的auto_ptr所拥有。那么,在拷贝构造或赋值操作时,我们必须作特殊的处理来保证这个特性。auto_ptr的做法是“所有权转移”,即拷贝或赋值的源对象将失去对“裸”指针的所有权,所以,与一般拷贝构造函数,赋值函数不同, auto_ptr的拷贝构造函数,赋值函数的参数为引用而不是常引用(const
reference).当然,一个auto_ptr也不能同时拥有两个以上的“裸”指针,所以,拷贝或赋值的目标对象将先释放其原来所拥有的对象。
这里的注意点是:
1) 因为一个auto_ptr被拷贝或被赋值后, 其已经失去对原对象的所有权,这个时候,对这个auto_ptr的提领(dereference)操作是不安全的。如下:
int* p = new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2 = ap1;
cout<<*ap1; //错误,此时ap1只剩一个null指针在手了
2)将auto_ptr作为函数参数按值传递
因为在函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的auto_ptr(拷贝构造),这样,传入的实参auto_ptr就失去了其对原对象的所有权,而该对象会在函数退出时被局部auto_ptr删除。如下:
void f(auto_ptr<int> ap){cout<<*ap;}
auto_ptr<int> ap1(new int(0));
f(ap1);
cout<<*ap1; //错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了。
【注意】因为这种情况太隐蔽,太容易出错了, 所以auto_ptr作为函数参数按值传递是一定要避免的。或许大家会想到用auto_ptr的指针或引用作为函数参数或许可以,但是仔细想想,我们并不知道在函数中对传入的auto_ptr做了什么, 如果当中某些操作使其失去了对对象的所有权, 那么这还是可能会导致致命的执行期错误。 也许,用const reference的形式来传递auto_ptr会是一个不错的选择。
3)我们可以看到拷贝构造函数与赋值函数都提供了一个成员模板在不覆盖“正统”版本的情况下实现auto_ptr的隐式转换。如我们有以下两个类
class base{};
class derived: public base{};
那么下列代码就可以通过,实现从auto_ptr<derived>到auto_ptr<base>的隐式转换,因为derived*可以转换成base*类型
auto_ptr<base> apbase = auto_ptr<derived>(new derived);
4) 因为auto_ptr不具有值语义(value semantic), 所以auto_ptr不能被用在STL标准容器中。
所谓值语义,是指符合以下条件的类型(假设有类A):
A a1;
A a2(a1);
A a3;
a3 = a1;
那么
a2 == a1, a3 == a1
很明显,auto_ptr不符合上述条件,而我们知道stl标准容器要用到大量的拷贝赋值操作,并且假设其操作的类型必须符合以上条件。
三,提领操作(dereference)
提领操作有两个操作,一个是返回其所拥有的对象的引用, 另一个是则实现了通过auto_ptr调用其所拥有的对象的成员。如:
struct A
{
void f();
}
auto_ptr<A> apa(new A);
(*apa).f();
apa->f();
当然, 我们首先要确保这个智能指针确实拥有某个对象,否则,这个操作的行为即对空指针的提领是未定义的。
四,辅助函数
1) get用来显式的返回auto_ptr所拥有的对象指针。我们可以发现,标准库提供的auto_ptr既不提供从“裸”指针到auto_ptr的隐式转换(构造函数为explicit),也不提供从auto_ptr到“裸”指针的隐式转换,从使用上来讲可能不那么的灵活, 考虑到其所带来的安全性还是值得的。
2) release
用来转移所有权
3) reset,用来接收所有权,如果接收所有权的auto_ptr如果已经拥有某对象, 必须先释放该对象。
可见,auto_ptr短短百来行的代码,还是包含了不少"玄机"的。
分享到:
相关推荐
在 C++ 中,有四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,每种智能指针都有其特点和使用场景。 一、auto_ptr auto_ptr 是 C++98 中引入的智能指针,它可以自动释放动态分配的内存。但是,auto_...
### C++ 智能指针 Auto_PTR 的细致而经典分析 #### 一、引言 C++ 是一门强大而灵活的语言,它不仅为开发者提供了底层控制能力,还通过多种高级特性来帮助开发者提高代码质量和可维护性。其中一项重要的功能就是...
尽管在C++11及以后版本中引入了更强大的智能指针如`unique_ptr`和`shared_ptr`,但了解`auto_ptr`的基本概念和用法对于理解智能指针仍然非常重要。 #### `auto_ptr`的概念与作用 `auto_ptr`主要用来管理动态分配的...
《C++智能指针——unique_ptr智能指针详解》 智能指针是C++中用于自动管理动态分配内存的一种工具,它可以确保在适当的时候自动释放内存,从而避免内存泄漏的问题。其中,`unique_ptr`是一种特殊的智能指针,它拥有...
C++ 智能指针(shared_ptr/weak_ptr)源码 源码位置:gcc-6.1.0\gcc-6.1.0\libstdc++-v3\include\tr1 这里只单列shared_ptr.h文件用于分析
详细讨论c++ auoto_ptr的原型,用法,以及注意事项
C++中的`auto_ptr`是旧版C++标准库中的一种智能指针,它主要用于管理动态分配的内存,确保在适当的时候自动释放内存,从而防止内存泄漏。在C++11之后,`auto_ptr`已被`unique_ptr`取代,因为`auto_ptr`有一些限制和...
本文主要讨论了三种智能指针:`shared_ptr`、`unique_ptr`和`weak_ptr`。 首先,`shared_ptr`是引用计数型智能指针,它维护了一个内部的引用计数,用于跟踪有多少个`shared_ptr`实例指向同一对象。当创建一个新的`...
在这个“智能指针shared_ptr的Demo”中,我们将深入探讨`shared_ptr`的用法和特点。 `shared_ptr`的主要功能是自动管理内存,当最后一个`shared_ptr`实例被销毁时,它会自动调用所指向对象的析构函数,从而释放内存...
C++智能指针shared_ptr分析 概要: shared_ptr是c++智能指针中适用场景多,功能实现较多的智能指针。它采取引用计数的方法来实现释放指针所指向的资源。下面是我代码实现的基本功能。 实例代码: template class ...
标题与描述均提到“auto_ptr再回忆”,暗示文章将通过一个故事的形式,回顾与探讨C++中`auto_ptr`的使用及其...但对于C++开发者而言,理解`auto_ptr`的历史背景和其潜在问题,仍然是理解和掌握智能指针机制的重要一步。
标题中的“自己实现的auto_ptr”指的是用户自行编写的一个智能指针类,模仿了C++标准库中的`std::auto_ptr`。`std::auto_ptr`是C++标准库中的一个智能指针,用于管理动态分配的对象,它会在适当的时候自动删除所指向...
本文将深入探讨C++中的`auto_ptr`,一种早期的智能指针,尽管在C++11标准中已被`unique_ptr`取代,但它仍然是理解智能指针工作原理的良好起点。 智能指针的基础原理在于,它是一个类,能够通过构造函数绑定到一个...
尽管如此,理解`auto_ptr`的工作原理仍然是学习C++历史和理解智能指针概念的重要部分。 `auto_ptr`的主要特点和用法如下: 1. **所有权管理**:`auto_ptr`对象一旦被创建并初始化为指向由`new`操作符分配的内存,...
《C与C++标准类库及函数》是一个深入探讨C和C++编程语言中标准库的资源,包含了大量的函数和类库信息。这个压缩包文件提供了CHM( Compiled Help Manual)格式的手册,这是一种常见的帮助文档格式,通常用于存放电子...
### C++ 智能指针详解:std::auto_ptr #### 一、引言 在C++中,由于缺乏自动内存管理机制,程序员需要手动处理由`new`分配的内存资源,通常需要通过`delete`操作来释放这些内存。然而,实际编程过程中经常会出现...
`std::shared_ptr`是C++标准库中的一个智能指针类型,属于弱所有者(weak ownership)的智能指针,用于管理动态分配的对象。 智能指针的核心理念在于自动管理对象的生命周期。当不再有智能指针指向一个对象时,该...
在C++编程中,智能指针(Smart Pointer)是一种非常重要的概念,它为管理动态内存提供了更加安全和方便的方式。智能指针本质上是封装了原始指针的对象,它能够自动管理所指向的对象生命周期,防止内存泄漏。在C++11...
通过深入学习和实践这些资料,开发者不仅能掌握C/C++指针的基本操作,还能了解如何在实际编程中安全有效地利用指针,提升程序设计能力。指针的理解和运用是成为一名熟练的C/C++程序员的关键步骤。