1, auto_ptr类

auto_ptr是一个模板类,定义如下:

template <typename Type>
class
 auto_ptr {...};

它存储的是一个指向Type的指针。

顾名思义,auto_ptr是一种智能指针,它包含一个动态分配内存的指针,并在它生命周期结束的时候,销毁包含的指针所指向的内存。


例1:

void f()

{

Type* pt(new Type);

//一些代码...

delete pt;

    }

这样的代码很常见,但它有可能造成内存泄露。首先你用了new,你就要记得用delete,但即使你记住了用delete,还是会出问题。如果f()在执行delete pt之前,就抛出了异常,函数返回了。那么这个分配的对象就没被删除。


使用auto_ptr,很优雅的解决了这些问题。

例2:

         void f()

{

auto_ptr<Type> pt(new Type);

//一些代码...
        }

现在的代码,不会泄露Type类型的对象。不管是函数正常结束,还是抛出异常结束,都会调用pt的析构函数,从而删除分配的对象。

2, auto_ptr构造函数

构造函数1:explicit auto_ptr(Type* _Ptr =
0) throw( );

auto_ptr<int> pt;                           //包含一个int*的指针,并初始化为NULL

auto_ptr<int> pt(new int(123)); //包含一个int*的指针,并初始化为123的地址

auto_ptr<int> pt = new int(123); //error!构造函数声明为explicit


构造函数2:auto_ptr(auto_ptr<Type>& _Right) throw(
);

            int* ptr = new int();

auto_ptr<int> pt1(ptr); //构造函数1

auto_ptr<int> pt2(pt1); //将pt1的使用权转给pt2,注意pt1指向NULL了

//pt1调用了本身的release()函数,将内部指针地址传给pt2

构造函数3:template<typename Other>

auto_ptr(auto_ptr<Other>& _Right) throw(
);

声明这样一个拷贝构造函数的目的,就是为了派生类指针能转换成基类的指针。

例:

      class Base { };

      class Derived : public Base { };

auto_ptr<Derived> pDerived(new Derived);

auto_ptr<Base>    pBase(pDerived);           //让这样的代码能通过编译器

其本质是为了让,auto_ptr类内部的Derived*转换为Base*


构造函数4:auto_ptr(auto_ptr_ref<Type> _Right) throw(
);

//暂略

3, auto_ptr成员函数

成员函数1:Type* get( ) const throw( );

获得包含指针的地址

int* ptr = new int(123);

auto_ptr<int> pt(ptr);

assert(pt.get() == ptr); //相等,指向同一地址

成员函数2:Type* release( ) throw( );

返回包含指针的地址,并将包含指针设为NUll

string* pstr = new string("hello");

auto_ptr<string> pt(pstr);

pt.release();   //不在指向string对象

//此时,pt.get()等于NULL

delete pstr;    //应该手动删除pstr指向的内存块

成员函数3:void reset(Type* _Ptr
= 0);

double* pdouble1 = new double(3.14);

double* pdouble2 = new double(1.23);

auto_ptr<double> pt1(pdouble1);

pt1.reset(pdouble2);  //将删除pt1所指向的内存块就是pdouble1指向的那块

//此时,pt.get()等于pdouble2

cout << *pdouble1;   //error,pdouble已经是野指针了。

4, 使用总结

1,auto_ptr存储的指针应该为NULL或者指向动态分配的内存块。

2,auto_ptr存储的指针应该指向单一物件(是new出来的,而不是new[]出来的)。

3,两个auto_ptr对象不会同时指向同一块内存块。要明白2个auto_ptr对象赋值会发生什么。

4,千万不要把auto_ptr对象放在容器中。

5,当将auto_ptr作为函数参数时,最好声明为const auto_ptr<T>&(by const ref).当函数返回值可以简单的传值(by value).

【VS开发】【C++开发】正确使用auto_ptr智能指针的更多相关文章

  1. C++ auto_ptr智能指针的用法

    C++中指针申请和释放内存通常采用的方式是new和delete.然而标准C++中还有一个强大的模版类就是auto_ptr,它可以在你不用的时候自动帮你释放内存.下面简单说一下用法. 用法一: std: ...

  2. c++ auto_ptr智能指针

    c++ auto_ptr智能指针 该类型在头文件memory中,在程序的开通通过 #include<memory> 导入,接下来讲解该智能指针的作用和使用. 使用方法: auto_ptr& ...

  3. shared_ptr 和auto_ptr智能指针

    shared_ptr:计数的智能指针 它是一个包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时 ...

  4. c++ auto_ptr 智能指针

    c++使用智能指针应该保证无论在何种情况下,只要自己被摧毁,就一定连带释放其所有资源,而由于智能型指针本身就是区域变量, 所以无论是正常退出,还是异常退出,只要函数退出,它就一定销毁 常数型auto_ ...

  5. boost准模板库scoped_ptr指针的使用以及auto_ptr智能指针的对照

    首先我们看看scoped_ptr的基本使用,包括了swap(),get(),reset()的使用,重要的提醒是作用域结束的时候会自己主动析构,无需手动的释放资源: #include<boost/ ...

  6. auto_ptr智能指针

    C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理. 使用std::auto_ptr,要#include <memory>.

  7. 智能指针剖析(上)std::auto_ptr与boost::scoped_ptr

    1. 引入 C++语言中的动态内存分配没有自动回收机制,动态开辟的空间需要用户自己来维护,在出函数作用域或者程序正常退出前必须释放掉. 即程序员每次 new 出来的内存都要手动 delete,否则会造 ...

  8. C++智能指针剖析(上)std::auto_ptr与boost::scoped_ptr

    1. 引入 C++语言中的动态内存分配没有自动回收机制,动态开辟的空间需要用户自己来维护,在出函数作用域或者程序正常退出前必须释放掉. 即程序员每次 new 出来的内存都要手动 delete,否则会造 ...

  9. 智能指针auto_ptr & shared_ptr

    转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...

随机推荐

  1. Linux操作系统常用命令合集——第三篇-系统管理操作(25个命令)

    1.whoami [命令作用] 显示当前登录有效用户名称 [命令语法]  whoami    [选项] [常用选项] 无 [参数说明] 用户名称 [命令示例] 显示当前登录有效用户名称 # whoam ...

  2. java1.8新特性之stream流式算法

    在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: List& ...

  3. python去掉字符串中重复字符的方法

      If order does not matter, you can use   foo = "mppmt" "".join(set(foo)) set() ...

  4. Hbase 错误记录分析(1) region超时问题

    错误现象: 默认等待时间是60秒,超过这个时间就报超时问题了.因此需调整超时时间,默认为60秒,在配置文件 hbase-site.xml中: 调整成10分钟 <property>    & ...

  5. Tkinter 之OptionMenu下拉选择菜单

    一.代码示例 import tkinter as tk window = tk.Tk() # 设置窗口大小 winWidth = 600 winHeight = 400 # 获取屏幕分辨率 scree ...

  6. uiautomator代码例子--java

    在androidtest下创建文件Ui2Test.java package com.example.myapplication; import android.app.Instrumentation; ...

  7. HashMap 在高并发下引起的死循环

    HashMap 基本实现(JDK 8 之前) HashMap 通常会用一个指针数组(假设为 table[])来做分散所有的 key,当一个 key 被加入时,会通过 Hash 算法通过 key 算出这 ...

  8. java面向对象-进度2

    1.面向对象的五个基本原则 三个基本元素: 1. 封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对象, ...

  9. Git git rm和git rm --cached

    git rm 和 git rm --cached 的区别 git rm file git commit -m "xxx" git push origin master 删除本地及仓 ...

  10. zsh: no matches found

    具体原因: 因为zsh缺省情况下始终自己解释这个 *.h,而不会传递给 find 来解释. 解决办法: 在~/.zshrc中加入: setopt no_nomatch, 然后进行source .zsh ...