凌云的博客

行胜于言

漫谈 C++ 智能指针 01

分类:c++| 发布时间:2015-09-17 23:00:00


什么是智能指针

众所周知,与其他大多数的现代语言不一样,C++ 并没有垃圾回收机制。 因此,在智能指针发明之前,资源泄露对于 C++ 程序来说是一个常见的错误。 在 C++ 中,智能指针通常被实现为模板仿真类,也就是说通过重载某些符号运算符 (比如,解引用,赋值等)来模拟普通(裸)指针的行为,同时提供额外的资源管理特性。

对象创建

我们可以通过 new 来创建一个对象,并且在使用完后用 delete 释放内存空间:

bool some_func()
{
    some_type *p = new some_type();
    // do something
    delete p;
    return true;
}

当然,直接使用 new、delete 很容易由于在某些情况忘记 delete 而导致内存泄露:

bool some_func()
{
    some_type *p = new some_type();
    // do something
    if (failed) {
        // Oops, memory leak
        return false;
    }

    delete p;
    return true;
}

可以通过使用 auto_ptr 智能指针解决这个问题:

bool some_func()
{
    std::auto_ptr<some_type> p;
    some_type *tmp = new some_type();
    if (!tmp)
        return false;

    p.reset(tmp);
    // do something
    if (failed) {
        // Ok, it will delete auto
        return false;
    }

    // do not need to delete now
    return true;
}

当然,在 C++11 以后,auto_ptr 已经被标记为 deprecated 不推荐使用了, 在 C++11 中推荐的方法为:

bool some_func()
{
    auto p = std::make_shared<some_type>(constructor, parameters, here);
    // do something
    if (failed) {
        // Ok, it will delete auto
        return false;
    }

    return true;
}

智能指针的简单实现

上面已经简单地说了如何通过使用智能指针来防止内存泄露。 知其然而知其所以然,下面来实现一个简单的智能指针:

class smart_ptr
{
public:
    explicit smart_ptr(some_type *p = 0): p_(p) {}
    ~smart_ptr() {
        clean();
    }

    void reset(some_type *p) {
        clean();
        p_ = p;
    }

    void clean() {
        if (p_) {
            delete p_;
            p_ = 0;
        }
    }
private:
    some_type *p_;
};

bool some_func()
{
    smart_ptr p;
    some_type *tmp = new some_type();
    if (!tmp)
        return false;

    p.reset(tmp);
    // do something
    if (failed) {
        // Ok, it will delete auto
        return false;
    }

    return true;
}