第二讲 auto_ptr智能指针

auto_ptr 不可被共享,只能指向一个对象

auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:
int* p = new int(0);
auto_ptr<int> ap(p);
从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。
这里我们有几点要注意:
1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:
int* p = new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p);
因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr.
2) 考虑下面这种用法:
int* pa = new int[10];
auto_ptr<int> ap(pa);
因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。
3) 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。
4) 因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:
~auto_ptr() throw() 
{
 if(ap) delete ap;
}

// STL.cpp : 定义控制台应用程序的入口点。
//
//智能指针在其生命周期结束后会自动调用delete
#include "stdafx.h"
#include<iostream>
#include<memory>
using namespace std;

class WebSite
{
public:
    WebSite(int x){i = x;cout << i << "调用构造函数" << endl;}
    ~WebSite(){cout << "调用析构函数" << endl;}
    void output(){cout << "output" << endl;}
private:
    int i;

};
int _tmain(int argc, _TCHAR* argv[])
{
    auto_ptr<WebSite> autop1(new WebSite(4));//定义了一个WebSite类的指针autop1
    auto_ptr<WebSite> autop2(new WebSite(7));
    autop1->output();
    cout << autop1.get() << endl;        //得到auto的一个指针
    cout << autop2.get() << endl;
    //autop1.reset();                        //将auto指向NULL
    //cout << autop1.get() << endl;
    ////autop1->output();                    //reset之后auto不可以再使用了

    autop1 = autop2;            //析构原来autop1指向的地址,将autop2指向的之地址赋给autop1。
                                //也就是说智能指针只能对一个对象并保持该地址
    cout << autop1.get() << endl;
    cout << autop2.get() << endl;

    return 0;
}

shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷。

posted @ 2014-06-24 11:55  击进的Cocos  阅读(223)  评论(0编辑  收藏  举报