智能指针

众所周知,在C++11以前,C++的内存释放是众多程序员头疼的问题,这也是导致使用C++开发效率低下的原因之一,为此C++11引入了智能指针这个概念。
原理
智能指针实际上采用引用计数的方法,调用构造函数时,引用计数默认初始化为1,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。
实现
在C++11中,智能指针采用类模板,该类模板包含了一个引用计数的类。程序员定义的每个类,编译器就会让该类继承引用计数的类。代码实现:

class RefCount { public: RefCount():crefs(0) {} virtual ~RefCount() {}void upCount() { ++crefs; } void downCount() { if(--crefs == 0) delete this; }private: int crefs; }; template class SmartPtr{ public: SmartPtr(T* p): ptr(p) { ptr->upCount(); } ~SmartPtr() {}T* operator ->() const { return ptr; }T& operator *() const { return *ptr; }SmartPtr& operator =(T* p) { ptr->downCount(); p->upCount(); ptr = p; return *this; }SmartPtr(const SmartPtr& p) { ptr = p; ptr->upCount(); } operator T*() const { return ptr; }SmartPtr& operator = (SmartPtr& p) { return operator =((T*)p); } private: T* ptr; };

C++11中的 智能指针
share_ptr 允许多个指针指向同一个对象;
unique_ptr 则单独占有一个对象;
weak_ptr 是一种弱引用, 指向 share_ptr 所管理的对象。
推荐使用make_shared 而不是 new 使用make_shared就能在分配对象的同时将 shared_ptr 与之绑定,从而避免无意中将同一内存绑定到多个独立创建的shared_ptr 上
weak_ptr可以用来解决循环引用 因为 weak_ptr 是弱引用,weak_ptr 的构造和析构不会导致引用计数的增加或者减少
例如:
#include #include using namespace std; class B; class A { public: shared_ptr pb; //weak_ptr pb; A() { cout << "construct A " << endl; } ~A() { cout << "deconstruct A" << endl; } }; class B { public: shared_ptr pa; //weak_ptr pa; B() { cout << "construct B" << endl; } ~B() { cout << "deconstruct B" << endl; } }; int main() { shared_ptr ptrA(new A()); shared_ptr ptrB(new B()); cout << ptrA.use_count() << endl; cout << ptrB.use_count() << endl; ptrA->pb = ptrB; ptrB->pa = ptrA; cout << ptrA.use_count() << endl; cout << ptrB.use_count() << endl; return 0; }

如果使用 share_ptr 在构造函数内,结果将输出
construct A
construct B
1
1
2
2
并没有调用析构函数,导致内存泄漏
如果使用 weak_ptr 在构造函数内,结果将输出
construct A
construct B
1
1
1
1
deconstruct B
deconstruct A
【智能指针】正确调用析构函数,内存被全部释放

    推荐阅读