C++ 智能指针auto_ptr详解
2014-06-15 22:31
489 查看
1. auto_ptr 的设计动机:
函数操作经常依照下列模式进行:
获取一些资源
执行一些动作
释放所获取的资源
那么面对这些资源的释放问题就会出现下面的两种情况:
一开始获得的资源被绑定于局部对象,那么当函数退出的时候,这些局部对象的析构函数被自动的调用,从而自动释放掉这些资源;
一开始获得的资源是通过某种显示手段获取,而且并没有绑定在任何对象身上,那么必须以显式的方式释放。这种情况常常发生在指针身上;
例子:
上述代码的真正的问题在于: 一旦在...中的某处发生异常,那么f()函数将立即退出,根本不会去调用函数尾端的delete语句。结果可能会造成内存的遗失,或者称为资源的遗失。
上述问题的一个解决方案是:
为了在异常发生时处理对象的删除工作,程序代码就会变得非常复杂和累赘!
为此,引入了智能指针的概念:
智能指针应该保证:无论在何种情形下,只要自己被销毁,就一定要连带释放其所指向的资源。由于智能指针本身就是区域变量,所以无论是正常推出,还是异常推出,它都一定被销毁,auto_ptr正是这种指针。
auto_ptr是这样的一种指针: 它是"其所指向的对象"的拥有者。所以,当身为对象拥有者的auto_ptr被销毁时,该对象也将被销毁。auto_ptr要求一个对象只能有一个拥有者,严禁一物二主。(天地之间物各有主,苟非吾之所有,虽一毫而莫取)。
下面我们通过一个实例来认识auto_ptr的使用:
初始化一个auto_ptr时,将一个指针作为参数传递给auto_ptr的构造函数。而不能使用赋值操作符。
2. auto_ptr拥有权的转移:
auto_ptr所界定的是一种严格的拥有权观念。也就是说,由于一个auto_ptr会删除其所指向的对象,所以这个对象绝对不能被其他对象同时"拥有"。绝对不可以出现多个
auto_ptrs拥有同一个对象。
那么auto_ptr的copy构造函数和assignment操作符该如何运作呢?
另auto_ptr的copy构造函数和assignment操作符将对象的拥有权交出去!
上面对象的拥有权从ptr1交到ptr2的时候,再使用ptr1去getMsg的时候,会出现"段错误"提示。
上面代码的结果是:
表明: 当ptr2被赋值前正拥有另一个对象,赋值动作发生时会发生delete,将该对象删除。
函数操作经常依照下列模式进行:
获取一些资源
执行一些动作
释放所获取的资源
那么面对这些资源的释放问题就会出现下面的两种情况:
一开始获得的资源被绑定于局部对象,那么当函数退出的时候,这些局部对象的析构函数被自动的调用,从而自动释放掉这些资源;
一开始获得的资源是通过某种显示手段获取,而且并没有绑定在任何对象身上,那么必须以显式的方式释放。这种情况常常发生在指针身上;
例子:
void f() { ClassA* ptr = new ClassA(); ... delete ptr; }
上述代码的真正的问题在于: 一旦在...中的某处发生异常,那么f()函数将立即退出,根本不会去调用函数尾端的delete语句。结果可能会造成内存的遗失,或者称为资源的遗失。
上述问题的一个解决方案是:
void f() { ClassA* ptr = new ClassA(); try { ... } catch(...) { delete ptr; throw; } delete ptr; }
为了在异常发生时处理对象的删除工作,程序代码就会变得非常复杂和累赘!
为此,引入了智能指针的概念:
智能指针应该保证:无论在何种情形下,只要自己被销毁,就一定要连带释放其所指向的资源。由于智能指针本身就是区域变量,所以无论是正常推出,还是异常推出,它都一定被销毁,auto_ptr正是这种指针。
auto_ptr是这样的一种指针: 它是"其所指向的对象"的拥有者。所以,当身为对象拥有者的auto_ptr被销毁时,该对象也将被销毁。auto_ptr要求一个对象只能有一个拥有者,严禁一物二主。(天地之间物各有主,苟非吾之所有,虽一毫而莫取)。
下面我们通过一个实例来认识auto_ptr的使用:
#include <iostream> #include <string> #include <memory> using namespace std; class Test { public: Test(const string& psg); string getMsg(); private: string msg; }; Test::Test(const string& psg) { msg = psg; } string Test::getMsg() { return msg; } int main(void) { std::auto_ptr<Test> ptr(new Test("This is the end of the world!")); cout<<ptr->getMsg()<<endl; return 0; }
初始化一个auto_ptr时,将一个指针作为参数传递给auto_ptr的构造函数。而不能使用赋值操作符。
2. auto_ptr拥有权的转移:
auto_ptr所界定的是一种严格的拥有权观念。也就是说,由于一个auto_ptr会删除其所指向的对象,所以这个对象绝对不能被其他对象同时"拥有"。绝对不可以出现多个
auto_ptrs拥有同一个对象。
那么auto_ptr的copy构造函数和assignment操作符该如何运作呢?
另auto_ptr的copy构造函数和assignment操作符将对象的拥有权交出去!
// initialize an auto_ptr with a new object std::auto_ptr<Test> ptr1(new Test("This is the end of the world!")); // copy the auto_ptr // ~ transfers ownership from ptr1 to ptr2 std::auto_ptr<Test> ptr2(ptr1); cout<<ptr1->getMsg()<<endl;
上面对象的拥有权从ptr1交到ptr2的时候,再使用ptr1去getMsg的时候,会出现"段错误"提示。
#include <iostream> #include <string> #include <memory> using namespace std; class Test { public: Test(const string& psg,const int& id); ~Test(); string getMsg(); private: string msg; int id; }; Test::Test(const string& psg,const int& pid) { msg = psg; id = pid; } Test::~Test() { cout<<"Delete "<<id<<" "<<endl; } string Test::getMsg() { return msg; } int main(void) { std::auto_ptr<Test> ptr1(new Test("This is ptr1",1)); std::auto_ptr<Test> ptr2(new Test("This is ptr2",2)); ptr2 = ptr1; return 0; }
上面代码的结果是:
Delete 2 Delete 1
表明: 当ptr2被赋值前正拥有另一个对象,赋值动作发生时会发生delete,将该对象删除。
相关文章推荐
- [转]C++智能指针(auto_ptr)详解
- C++智能指针(auto_ptr)详解
- C++智能指针(auto_ptr)详解 (转载)
- 详解C++各种智能指针: auto_ptr, shared_ptr, weak_ptr, scoped_ptr
- C++中的auto_ptr智能指针的作用及使用方法详解
- C++智能指针(auto_ptr)详解
- C++中auto_ptr智能指针的用法详解
- C++ auto_ptr 智能指针
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- C++ 中的auto_ptr智能指针
- C++学习之auto_ptr智能指针
- C++ auto_ptr智能指针的用法
- C++智能指针:auto_ptr、shared_ptr、weak_ptr等
- C++ 智能指针auto_ptr
- 以对象管理资源——C++智能指针auto_ptr简介
- [转载]C++的智能指针auto_ptr做了些什么
- C++ auto_ptr智能指针的用法
- 探究c++智能指针中auto_ptr_ref的存在意义
- C++ auto_ptr智能指针的详细用法和注意事项
- c++ 模板学习笔记:类模板模拟auto_ptr智能指针(权哥)