C++——智能指针

C++的内存管理是一个很大的问题,C++程序员总是会无意间的造成内存泄漏的问题,C++98给出了智能指针的解决方案,智能指针会在销毁指针的时候自动销毁指针指向的内容(例如栈解退)。

智能指针是一个模板类,可以看成一个被包装过的指针。他的构造函数如下

template 
class auto_ptr
{
public:
    explicit auto_ptr(X * p=0) throw() {}
};

他将获得一个指向X的指针。

使用智能指针后的程序

#include 
#include 
#include 
using namespace std;

int main()
{
    auto_ptr ps(new string ("hello"));
    //don't need delete
    cout << *ps;
    return 0;
}

运行结果

在只能指针ps被销毁的时候,会调用其析构函数释放ps指向的内容。

我们也可以写一个自己的简单的智能指针

include 
#include 
#include 
using namespace std;
template 
class my_auto_ptr
{
private:
    T * ptr;
public:
    explicit my_auto_ptr(T * p= nullptr) : ptr(p) {}
    ~my_auto_ptr()
    {
        delete ptr;
    }
    T & operator*()
    {
        return *ptr;
    }
};
int main()
{
    my_auto_ptr ps (new string("hello"));
    cout << *ps;
    return 0;
}

想进一步包装的话还可以重载-> =等运算符。

这种智能指针(auto_ptr)在进行赋值运算时可能会有问题,又或者是不经意间重复释放内存,有以下几种解决方案

1.重载=进行深拷贝

2.建立所有权的概念,每个对象只有一个智能指针拥有它,=是所有权的转让

unique_ptr

3.创建智能性更高的指针,记录构造函数和析构函数的次数,判断是否释放。

shared_ptr


 unique_ptr的使用比较严格

编译器不允许将将这类对象赋值给另一个对象,但如果对象是一个临时的右值则可以(如返回值)。

int main()
{
    unique_ptr ps;
    unique_ptr pd;
    pd = ps;    //error
    return 0;
}

 这样可以,这将"hello"的所有权从temp变成了主函数中的ps

unique_ptr t(const char * s)
{
    unique_ptr temp(new string(s));
    return temp;
}
int main()
{
    unique_ptr ps;
    ps = t("hello");
    cout << *ps;
    return 0;
}

注意:智能指针的本质也是使用new和delete,其中,只有unique_ptr有[]delete的版本,不要让只能指针指向非new出来的对象。

 在unique_ptr为右值时,可将其赋值给shared_ptr,因为后者是计数处理。

shared_ptr有一个构造函数,可将右值unique_prt转换为shared_prt,shared_ptr将接管原来unique_prt接管的对象。

智能指针的选择

如果要将多个指针指向同一个对象,应选择shared_ptr

SLT很多算法都支持赋值和赋值操作,可用于shared_prt

不需要用多个指针指向同一个对象, 可使用unique_ptr

用new分配的内存,并返回该内存的指针,unique_prt是个不错的选择

你可能感兴趣的:(C++,c++,指针)