C++ 智能指针auto_ptr详解
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详解的更多相关文章
- C++智能指针(auto_ptr)详解
		
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...
 - c++ 智能指针用法详解
		
本文介绍c++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被c++11弃用. 为什么要使用智能 ...
 - 19.C++-(=)赋值操作符、智能指针编写(详解)
		
(=)赋值操作符 编译器为每个类默认重载了(=)赋值操作符 默认的(=)赋值操作符仅完成浅拷贝 默认的赋值操作符和默认的拷贝构造函数有相同的存在意义 (=)赋值操作符注意事项 首先要判断两个操作数是否 ...
 - C++11 shared_ptr(智能指针)详解
		
要确保用 new 动态分配的内存空间在程序的各条执行路径都能被释放是一件麻烦的事情.C++ 11 模板库的 <memory> 头文件中定义的智能指针,即 shared _ptr 模板,就是 ...
 - C++智能指针--auto_ptr指针
		
auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同一时候被分给两个拥有者.当 ...
 - 自己动手实现智能指针auto_ptr
		
面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...
 - C++ 智能指针auto_ptr
		
template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...
 - 关于智能指针auto_ptr
		
智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...
 - C++中的智能指针(auto_ptr)
		
实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...
 
随机推荐
- HDOJ-ACM1014(JAVA)
			
这道题题意: 求最大公约数,最大公约数是1,则GOOD,否则BAD 注意: 输出时,如果是System.out.printf("%10d%10d Good Choice\n\n&quo ...
 - iOS xcodebuild 打包app
			
1.传统的app打包(没有使用cocopods) 在打包之前,先把证书和配置文件选好. step1:打开终端,cd 进入到工程目录中 step2:xcodebuild clean(如果buid文件存在 ...
 - POJ1838
			
poj 1838 这道题主要是对并查集的考察,在这道题的解题过程中主要用到的算法就是并查集中的最基本的makeSet,findSet,unionSet 即前篇文章中所提到的: makeSet(Elem ...
 - go语言与所谓的包
			
import后面接的是目录的名字,而不是所谓包的名字,并且如果一个目录下面还有目录的话都必须要写进去,比如: import "MyPackage" import "MyP ...
 - java中服务器启动时,执行定时任务
			
package com.ripsoft.util; import java.util.Calendar; import java.util.Timer; import javax.servlet.Se ...
 - 如何调试什么时候SaveFileDialog会被Dispose
			
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何调试什么时候SaveFileDialog会被Dispose.
 - PHP基本语法(一)
			
整形:就是对用整数 正整数与负整数整形的表示:int integer NOTICE:写整形的时候不要在外面再加引号了 浮点:就是小数 3.1415926Float 浮点 布尔值:男和女 真和假 阴和 ...
 - 基于 OAuth 安全协议的 Java 应用编程1
			
原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-oauth/index.html 參考博客:http://www.cnblogs.com/wan ...
 - Hadoop-2.2.0中文文档——MapReduce 下一代 -——集群配置
			
目的 这份文档描写叙述了怎样安装.配置和管理从几个节点到有数千个节点的Hadoop集群. 玩的话,你可能想先在单机上安装.(看单节点配置). 准备 从Apache镜像上下载一个Hadoop的稳定版本号 ...
 - Oracle Outline总结
			
一.基本概述 Oracle Outline,中文也称为存储大纲,是最早的基于提示来控制SQL运行计划的机制.也是9i以及之前版本号唯一能够用来稳定和控制SQL运行计划的工具. outline是一个hi ...