1. auto_ptr 的设计动机:

函数操作经常依照下列模式进行:

  • 获取一些资源
  • 执行一些动作
  • 释放所获取的资源

那么面对这些资源的释放问题就会出现下面的两种情况:

  • 一开始获得的资源被绑定于局部对象,那么当函数退出的时候,这些局部对象的析构函数被自动的调用,从而自动释放掉这些资源;
  • 一开始获得的资源是通过某种显示手段获取,而且并没有绑定在任何对象身上,那么必须以显式的方式释放。这种情况常常发生在指针身上;

例子:

 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 ;
}

初始化一个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",));
std::auto_ptr<Test> ptr2(new Test("This is ptr2",));
ptr2 = ptr1;
return ;
}

上面代码的结果是:

 Delete
Delete

表明: 当ptr2被赋值前正拥有另一个对象,赋值动作发生时会发生delete,将该对象删除。

C++ 智能指针auto_ptr详解的更多相关文章

  1. C++智能指针(auto_ptr)详解

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

  2. c++ 智能指针用法详解

    本文介绍c++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被c++11弃用. 为什么要使用智能 ...

  3. 19.C++-(=)赋值操作符、智能指针编写(详解)

    (=)赋值操作符 编译器为每个类默认重载了(=)赋值操作符 默认的(=)赋值操作符仅完成浅拷贝 默认的赋值操作符和默认的拷贝构造函数有相同的存在意义 (=)赋值操作符注意事项 首先要判断两个操作数是否 ...

  4. C++11 shared_ptr(智能指针)详解

    要确保用 new 动态分配的内存空间在程序的各条执行路径都能被释放是一件麻烦的事情.C++ 11 模板库的 <memory> 头文件中定义的智能指针,即 shared _ptr 模板,就是 ...

  5. C++智能指针--auto_ptr指针

    auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同一时候被分给两个拥有者.当 ...

  6. 自己动手实现智能指针auto_ptr

    面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...

  7. C++ 智能指针auto_ptr

    template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...

  8. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  9. C++中的智能指针(auto_ptr)

    实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...

随机推荐

  1. hadoop-2.6.0.tar.gz + spark-1.5.2-bin-hadoop2.6.tgz的集群搭建(单节点)

    前言 本人呕心沥血所写,经过好一段时间反复锤炼和整理修改.感谢所参考的博友们!同时,欢迎前来查阅赏脸的博友们收藏和转载,附上本人的链接.http://www.cnblogs.com/zlslch/p/ ...

  2. A Tour of Go Short variable declarations

    Inside a function, the := short assignment statement can be used in place of a var declaration with ...

  3. new Date() iso不支持兼容性问题

    在IOS5以上版本(不包含IOS5)中的Safari浏览器能正确解释出Javascript中的 new Date('2013-10-21') 的日期对象. 但是在IOS5版本里面的Safari解释ne ...

  4. HDU5100Chessboard(数论)

    HDU5100Chessboard(数论) 题目链接 题目大意:用k∗1的瓷砖区铺n∗n的矩形,问能铺上的最大的面积. 解题思路:这题没有直接得出结论:l = n%k, ans = max[(n^2 ...

  5. Dreamweaver中清除php代码中多余空行的方法

    使用DW自带的搜索功能,利用正则表达式 使用正则表达式搜索:\r\n\s*\r\n即可搜到代码中的空行,再用回车符\n替换即可消除代码中的多余空行

  6. hdu1430魔板(BFS+康托展开)

    做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...

  7. SQL Server解决死锁问题

    用以下语句查询所有死锁的进程号和表名: SELECT  request_session_id spid,  OBJECT_NAME(   resource_associated_entity_id   ...

  8. 关于Servlet中重定向

    public class Red1Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpSer ...

  9. iOS 网络编程:NSURLSession

    NSURLSession类和相关的类提供很多API来下载HTTP的内容.这些API提供多种delegate协议来支持验证和执行后台下载任务. 1 URL Session 设计概念 Session中的任 ...

  10. 删除主目录下的.ssh目录下文件对boot2docker启动影响

    现象: 1) boot2docker ssh需要输入密码 2) boot2docker start 或 up 需要输入密码 解决方法: 1)删除 /Users/sunzhaoyu/.boot2dock ...