6. 警惕智能指针作为參数!
1) 按值传递时,函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的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已经不再拥有不论什么对象了。
2) 出入的是引用或指针时,不会存在上面的拷贝过程。
但我们并不知道在函数中对传入的auto_ptr做了什么。假设其中某些操作使其失去了对对象的全部权。那么这还是可能会导致致命的运行期错误。
结论:const reference是智能指针作为參数传递的底线。
7. auto_ptr不能初始化为指向非动态内存
原因非常easy。delete 表达式会被应用在不是动态分配的指针上这将导致没有定义的程序行为。
8. auto_ptr经常使用的成员函数
1) get()
返回auto_ptr指向的那个对象的内存地址。例如以下例:
int* p = new int(33);
cout << "the adress of p:"<< p << endl;
auto_ptr<int> ap1(p);
cout << "the adress of ap1:" << &ap1 << endl;
cout << "the adress of theobject which ap1 point to: " << ap1.get() << endl;
输出例如以下:
the adress of p: 00481E00
the adress of ap1: 0012FF68
the adress of the object which ap1point to: 00481E00
第一行与第三行同样,都是int所在的那块内存的地址。
第二行是ap1这个类对象本身所在内存的地址。
2) reset()
又一次设置auto_ptr指向的对象。
类似于赋值操作,但赋值操作不同意将一个普通指针指直接赋给auto_ptr,而reset()同意。例如以下例:
auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) );
pstr_auto.reset( new string("Long -neck" ) );
在样例中。重置前pstr_auto拥有"Brontosaurus"字符内存的全部权,这块内存首先会被释放。之后pstr_auto再拥有"Long -neck"字符内存的全部权。
注:reset(0)能够释放对象。销毁内存。
3) release()
返回auto_ptr指向的那个对象的内存地址,并释放对这个对象的全部权。
用此函数初始化auto_ptr时能够避免两个auto_ptr对象拥有同一个对象的情况(与get函数相比)。
样例例如以下:
auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) );
auto_ptr< string > pstr_auto2(pstr_auto.get() ); //这是两个auto_ptr拥有同一个对象
auto_ptr< string > pstr_auto2(pstr_auto.release() ); //release能够首先释放全部权