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去释放内存.当然有利也有弊,也不是全然完美的. 本 ...
随机推荐
- Dllimport函数時无法在Dll中找到的入口点
今天開發客戶提供的一個dll時出現無法找到入口點問題,由於客戶也不能明確說明dll,所以一時不知道如何下手,經查詢後找到可通過vs自帶的dumpbin.exe查看. Dumpbin.exe位于 VS的 ...
- Linux为Tomecat指定JDK
在搭建Jenkin+Sonar集成时,由于系统环境配置了jdk1.7,但是jenkins在安装sonar的插件时,需要jdk1.8.,所以需要在Tomcat指定jdk1.8. (1)暂停Tomcat ...
- [置顶] 项目进阶 之 持续构建环境搭建(二)Nexus私服器
上一篇博文项目进阶 之 持续构建环境搭建(一)架构中,我们大致讲解了一下本系列所搭建环境的基本框架,这次开始我们进入真正的环境搭建实战.重点不在于搭建的环境是否成功和完善,而是在搭建过程中充分认识到每 ...
- GPUImage的简单使用
GPUImage 是一个开源的图像处理库,提供了非常多的滤镜效果来加工图片.GPUImage 并不像一般的第三方库可以直接拖入到工程中使用,而是需要先在本地编译,然后将编译后的文件拖入到工程中使用.配 ...
- wxPython 对话框关闭后进程无法退出的原因
wxPython中不要用对话框作为主程序wx.Dialog,这会导致程序关闭后进程无法退出.一种可行的做法是用wx.Frame代替
- [Unity] How to stop camera rendering?
http://answers.unity3d.com/questions/147988/how-to-pause-the-main-camera-.html I would simply pause ...
- 用mac自带的safari浏览器下载excel文件后面自带了.exe后缀
将 Content-Type 设为 application/vnd.ms-excel
- ubuntu上如何安装和卸载google chrome 浏览器
切换到安装文件目录 $ sudo dpkg -i file_name.deb 如果有错误,请运行以下命令 $ sudo apt-get -f install or $ sudo apt-get ins ...
- Windows Mobile 6.0 SDK和中文模拟器下载
[转] Windows Mobile 6.0 SDK和中文模拟器下载 Windows Mobile 6.5 模拟器 2010年12月06日 星期一 07:48 转载自 zhangyanle86 终于编 ...
- setvbuf
函数名: setvbuf 用 法: int setvbuf(FILE *stream, char *buf, int type, unsigned size); type : 期望缓冲区的类型: _I ...