自C++11起,C++标准库提供了智能指针
shared_ptr
操作引用计数实现共享式拥有的概念。多个智能指针可以指向相同的对象,这个对象和其相关资源会在最后一个被销毁时释放。
1 2 3 4 5 6 7 8 9 10 11 12
| class A { public: ~A() { cout << "释放A" << endl; } };
void test() { shared_ptr<A> a(new A()); }
|
虽然使用shared_ptr能够非常方便的为我们自动释放对象,但是还是会出现一些问题。最典型的就是循环引用问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class B; class A { public: ~A() { cout << "释放A" << endl; } shared_ptr<B> b; };
class B { public: ~B() { cout << "释放B" << endl; } shared_ptr<A> a; }; void test() { shared_ptr<A> a(new A()); shared_ptr<B> b(new B()); cout << a.use_count() << endl; a->b = b; b->a = a; }
|
weak_ptr
weak_ptr是为配合shared_ptr而引入的一种智能指针。主要用于观测资源的引用情况。
它的构造和析构不会引起引用记数的增加或减少。没有重载*和->但可以使用lock获得一个可用的shared_ptr对象。
配合shared_ptr解决循环引用问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class B; class A { public: ~A() { cout << "释放A" << endl; } weak_ptr<B> b; }; class B { public: ~B() { cout << "释放B" << endl; } weak_ptr<A> a; };
void test() { shared_ptr<A> a(new A()); shared_ptr<B> b(new B());
a->b = b; b->a = a; }
|
weak_ptr 提供expired 方法等价于 use_count == 0,当expired为true时,lock返回一个存储空指针的shared_ptr
unique_ptr
实现独占式引用,保证同一时间只有一个智能指针指向内部对象。
1
| unique_ptr<A> a(new A());
|
auto_ptr已经不推荐使用
手写智能指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| template <typename T> class Ptr { public: Ptr() { count = new int(1); t = 0; } Ptr(T *t):t(t) { count = new int(1); } ~Ptr() { if (--(*count) == 0) { if (t) { delete t; } delete count; t = 0; count = 0; } } Ptr(const Ptr<T> &p) { ++(*p.count); t = p.t; count = p.count; }
Ptr<T>& operator=(const Ptr<T>& p) { ++(*p.count); if (--(*count) == 0) { if (t) { delete t; } delete count; } t = p.t; count = p.count; return *this; } T* operator->() { return t; }
private: T *t; int *count; };
|
重载=为什么返回引用,而不是对象?
return *this后马上就调用拷贝构造函数,将*this拷贝给一个匿名临时对象,然后在把临时对象拷贝给外部的左值(a=b,a为左值),再释放临时对象。这样首先会造成不必要的开销。
nullptr
nullptr 出现的目的是为了替代 NULL。 同时拥有更多的特性 例如:可以调用到指针参数的函数。
1 2 3 4 5 6 7 8 9 10 11
| void test(int* i){ } void test(int i){ }
test(9);
test(nullptr);
|
版权声明: 此文章版权归Jack Ou所有,如有转载,请註明来自原作者