智能指针(Smart Point)

传统指针存在的问题

需要手段管理内存。

容易发生内存泄漏(忘记释放或出现异常等)。

释放之后产生野指针。


智能指针

智能指针就是为了解决传统指针存在的问题。

auto_ptr:属于C98标准,在C 11中已经不推荐使用(有缺陷,比如不能用于数组)。

shared_ptr:属于C++ 11标准。

unique_ptr:属于C++ 11标准。

注意:要包含#include <memory>

auto_ptr

已弃用。

shared_ptr

class Person
{
private:
    int age;
public:
    Person(int age = 0) : age(age) { cout << "Person()" << endl; }
    ~Person() { cout << "~Person()" << endl; }
    void  run() { cout << "Person::run() --- " << this->age << endl; }
};

int main()
{
    shared_ptr<Person> p(new Person());
    p->run();
    // 数组
    shared_ptr<Person[]> p2(new Person[5]);
    // 或者
    shared_ptr<Person> p3(new Person[5], [](Person *p) { delete[] p; });
    return 0;
}

shared_ptr的设计理念:多个shared_ptr可以指向同一一个对象,当最后一个shared_ptr在作用域范围内结束时,对象才会被自动释放。

可以通过一个已存在的智能指针初始化一个新的智能指针。

class Person
{
private:
    int age;
public:
    Person(int age = 0) : age(age) { cout << "Person()" << endl; }
    ~Person() { cout << "~Person()" << endl; }
    void  run() { cout << "Person::run() --- " << this->age << endl; }
};

int main()
{
    shared_ptr<Person> p(new Person());
    shared_ptr<Person> p2(p);
    return 0;
}

原理

一个shared_ptr会对一一个对象产生强引用(strong reference)。

每个对象都有个与之对应的强引|用计数,记录着当前对象被多少个shared_ptr强引用着。

可以通过shared_ptruse_ count函数获得强弓|用计数。

当有一-个新的shared_ptr指向对象时,对象的强引|用计数就会+1。

当有一个shared_ptr销毁时(比如作用域结束),对象的强引用计数就会-1。

当一个对象的强引用计数为0时(没有任何shared_ptr指向对象时),对象就会自动销毁。

循环引用

使用shared_ptr可能会导致循环引用,让对象都无法销毁。使用weak_ptr可以解决循环引用的问题。

unique_ptr

unique_ptr`也会对一-个对象产生强引用,它可以确保同一时间只有1个指针指向对象。

unique_ptr销毁时(作用域结束时),其指向的对象也就自动销毁了。

可以使用std: :move函数转移unique_ptr的所有权。

自实现

class Person
{
private:
    int age;
public:
    Person(int age = 0) : age(age) { cout << "Person()" << endl; }
    ~Person() { cout << "~Person()" << endl; }
    void  run() { cout << "Person::run() --- " << this->age << endl; }
};

template <class T>
class SmartPointer
{
private:
    T *obj;
public:
    SmartPointer(T *obj) : obj(obj) {  }
    ~SmartPointer()
    {
        if ( obj ) delete obj;
    }
    T *operator->()
    {
        return this->obj;
    }
};

int main()
{
    {
        SmartPointer<Person> p(new Person());
        p->run();
    }
    return 0;
}