1.智能指针

智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,

2. 最常用的智能指针

 1)std::auto_ptr,有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。

  2) C++11引入的unique_ptr, 也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。

例如:

std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; // 编译会出错
std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.

 3) C++11或boost的shared_ptr,基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放。

 4)C++11或boost的weak_ptr,弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。

3. 智能指针的实现

下面是一个基于引用计数的智能指针的实现,需要实现构造,析构,拷贝构造,=操作符重载,重载*-和>操作符。

template <typename T>
class SmartPointer {
public:
    //构造函数
    SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){
        if(p)
            *_reference_count = 1;
        else
            *_reference_count = 0;
    }
    //拷贝构造函数
    SmartPointer(const SmartPointer& src) {
        if(this!=&src) {
            _ptr = src._ptr;
            _reference_count = src._reference_count;
            (*_reference_count)++;
        }
    }
    //重载赋值操作符
    SmartPointer& operator=(const SmartPointer& src) {
        if(_ptr==src._ptr) {
            return *this;
        }
        releaseCount();
        _ptr = src._ptr;
        _reference_count = src._reference_count;
        (*_reference_count)++;
        return *this;
    }
     
    //重载操作符
    T& operator*() {
        if(ptr) {
            return *_ptr;
        }
        //throw exception
    }
    //重载操作符
    T* operator->() {
        if(ptr) {
            return _ptr;
        }
        //throw exception
    }
    //析构函数
    ~SmartPointer() {
        if (--(*_reference_count) == 0) {
            delete _ptr;
            delete _reference_count;
        }
    }
private:
    T *_ptr;
        size_t *_reference_count;
        void releaseCount() {
        if(_ptr) {
            (*_reference_count)--;
            if((*_reference_count)==0) {
                delete _ptr;
                delete _reference_count;
            }
        }
    }
};
  
int main()
{
    SmartPointer<char> cp1(new char('a'));
    SmartPointer<char> cp2(cp1);
    SmartPointer<char> cp3;
    cp3 = cp2;
    cp3 = cp1;
    cp3 = cp3;
    SmartPointer<char> cp4(new char('b'));
    cp3 = cp4;
}

转自:https://blog.csdn.net/worldwindjp/article/details/18843087 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐