版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/i_chaoren/article/details/82586456
1、基础概念
智能指针的一种通用实现技术是使用引用计数。智能指针类将一个计数器与智能指针指向的对象相关联,用来记录有多少个智能指针指向相同的对象,并在恰当的时候释放对象。
每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,引用计数加1;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
下图是shared_ptr的内存模型:
由图中可以看到,实际上引用计数、自定义销毁等都不是直接存储在shared_ptr中,而是通过一个指针指向的一个控制块存储的,控制块是动态分配的内存 。
下面是用类模板简单实现shared_ptr.
#include <iostream>
using namespace std;
template<typename T>
class SmartPointer {
private:
T* p_;
size_t* count_;
public:
SmartPointer(T* ptr = nullptr) : p_(ptr) {
if (p_) {
count_ = new size_t(1);
}
else {
count_ = new size_t(0);
}
}
SmartPointer(const SmartPointer& ptr) {
p_ = ptr.p_;
count_ = ptr.count_;
(*count_)++;
}
SmartPointer& operator=(const SmartPointer& ptr) {
if (p_ == ptr.p_) {
return *this;
}
if (p_) {
if (--(*count_) == 0) {
delete p_;
delete count_;
}
}
p_ = ptr.p_;
count_ = ptr.count_;
(*count_)++;
return *this;
}
~SmartPointer() {
if (--(*count_) == 0) {
delete p_;
delete count_;
}
}
size_t use_count() {
return *count_;
}
};
int main() {
SmartPointer<int> sp1(new int(10));
SmartPointer<int> sp2(sp1);
SmartPointer<int> sp3(new int(20));
sp2 = sp3;
std::cout << sp1.use_count() << std::endl;
std::cout << sp3.use_count() << std::endl;
}
2、智能指针带来的性能影响
1)shared_ptr的尺寸是裸指针的两倍。
2)会带来控制块的开销。
3)引用计数的递增和递减是原子操作,原子操作一般都比非原子操作慢。
3、使用weak_ptr解决shared_ptr的循环引用。
解决方案:将类A,B中的shared_prt改为weak_ptr即可,weak_ptr不会增加shared_ptr的引用计数
class B;
class A {
public:
weak_ptr<B> p;
//shared_ptr<B> p;
};
class B {
public:
weak_ptr<A> p;
//shared_ptr<A> p;
};
int main() {
while (true) {
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->p = pb;
pb->p = pa;
}
return 0;
}
参考文章: