现在的位置: 首页 > 综合 > 正文

使用auto_ptr类型的注意事项

2013年01月08日 ⁄ 综合 ⁄ 共 2703字 ⁄ 字号 评论关闭

2012-03-03 wcdj

先看一个例子:

#include <iostream>
#include <string>
#include <memory>// auto_ptr class

using std::cout;
using std::endl;
using std::string;
using std::auto_ptr;

void f1()
{
	int *ip = new int(123);// dynamically allocate a new object
	cout << "&ip = " << ip << "; *ip = " << *ip << endl;

	/* code that throws an exception that is not caught inside f1() */

	delete ip;
}

void f2()
{
	auto_ptr<int> ap(new int(456));// allocate a new object
	cout << "&ap = " << &ap << "; *ap = " << *ap << endl;

	/* code that throws an exception that is not caught inside f2() */

	// auto_ptr freed automatically when function ends
}

void f3()
{
	auto_ptr<string> ap_string(new string("delphiwcdj"));
	cout << "ap_string = " << *ap_string << endl;

	*ap_string = "gerry";
	cout << "ap_string = " << *ap_string << endl;

	if (ap_string->empty())
	{
		cout << "ap_string is empty" << endl;
	}
	else
	{
		cout << "ap_string is non-empty" << endl;
	}

}


int main() 
{
	cout << "auto_ptr usage\n" << endl;

	f1();

	f2();

	f3();

	return 0;
}
/*
g++ -Wall -g -o auto_ptr auto_ptr.cpp 

output:
auto_ptr usage

&ip = 0x804b008; *ip = 123
&ap = 0xbfa85d70; *ap = 456
ap_string = delphiwcdj
ap_string = gerry
ap_string is non-empty
*/

标准库的auto_ptr类是接受一个类型参数的模版,它为动态分配的对象提供异常安全。auto_ptr类在头文件memory中定义:
 

auto_ptr 类

auto_ptr<T> ap;

创建名为ap的未绑定的auto_ptr对象

auto_ptr<T> ap(p);

创建名为ap的auto_ptr对象,ap拥有指针p指向的对象。该构造函数为explicit

auto_ptr<T> ap1(ap2);

创建名为ap1的auto_ptr对象,ap1保存原来存储在ap2中的指针。将所有权转给ap1, ap2成为未绑定的auto_ptr对象

ap1 = ap2;

将所有权从ap2转给ap1。删除ap1指向的对象并且使ap1指向ap2指向的对象,使ap2成为未绑定的

~ap

析构函数。删除ap指向的对象

*ap

返回对ap所绑定的对象的引用

ap->

返回ap保存的指针

ap.reset(p);

如果p与ap的值不同,则删除ap指向的对象并且将ap绑定到p

ap.release();

返回ap所保存的指针并且使ap成为未绑定的

ap.get();

返回ap保存的指针

注意:
(1) auto_ptr只能用于管理从new返回的一个对象,它不能管理动态分配的数组。当auto_ptr被复制或赋值的时候,有不寻常的行为,因此,不能将auto_ptr存储在标准容器类型中。
(2) auto_ptr对象只能保存一个指向对象的指针,并且不能用于指向动态分配的数组,使用auto_ptr对象指向动态分配的数组会导致未定义的运行时行为。
(3) 每个auto_ptr对象绑定到一个对象或者指向一个对象。当auto_ptr对象指向一个对象的时候,可以说它“拥有”该对象。当auto_ptr对象超出作用域或者另外撤销的时候,就自动回收auto_ptr所指向的动态分配对象。

几点注意事项

1,为异常安全的内存分配使用 auto_ptr
f1()函数中,如果通过常规指针分配内存,此时在执行new和delete之间发生异常,并且该异常不被局部捕获,该内存将不会被回收。
f2()函数中,如果用一个auto_ptr对象来代替,将会自动释放内存,即使提早退出这个块也是这样。编译器保证在展开栈越过f2()函数之前运行auto_ptr对象的析构函数。

2,auto_ptr 是可以保存任何类型指针的模版

auto_ptr<string> ap(new string("My name is delphiwcdj"));

3,将 auto_ptr 绑定到指针
最常见的情况,是将auto_ptr对象初始化为由new表达式返回的对象的地址:
auto_ptr<int> ap(new int(1024));
这个语句将ap初始化为由new表达式创建的对象的地址,这个new表达式将对象初始化为1024。
注意:
接受指针的构造函数为explicit类型的构造函数,所以必须使用初始化的直接形式来创建auto_ptr对象,不能用隐式转换。

auto_ptr<int> ap = new int(1024); // error
auto_ptr<int> ap(new int(1024));  // ok, use direct initialization

4,使用auto_ptr对象
auto_ptr类定义了解引用操作符(*)和箭头操作符(->)的重载版本,因此可以用类似于使用内置指针的方式使用auto_ptr对象:

auto_ptr<string> ap(new string("My name is delphiwcdj"));
*ap = "gerry";// assigns a new value to the object to which ap points
string s = *ap;// initializes s as a copy of the object to which ap points
if (ap -> empty())// runs empty on the string to which ap points

注意:
auto_ptr的主要目的是,在保证自动删除auto_ptr对象引用的对象的同时,支持普通指针式行为。自动删除该对象这一行为导致在怎样复制和访问它们的地址值方面,auto_ptr与普通指针明显不同。

5,auto_ptr对象的复制和赋值是破坏性操作

待续

抱歉!评论已关闭.