C++11智能指针的原理与实现
1. 概述
- 智能指针是C++11引入的新特性,头文件<memory>
- 它实际是对一个普通指针封装成的类,并重载了*和->的两个操作符
2. 简单的使用
shared_ptr:
- 基于引用计数,用于多个指针指向同一个对象的情况,初始时计数+1,折构时计数-1,计数0时自动释放;
- sizeof(shared_ptr) = 16;
- 可以看到shared_ptr是普通指针大小两倍,因为它包含2个指针,一个指向有用内存,一个执行引用计数;
// 下面演示了shared_ptr的声明和自动释放的过程
class A {
public:
A(int x): data(x) {}
~A () {
cout << "release A: " << data << endl;
}
private:
int data;
};
int main(){
A a(5); // 后面打印release A: 5
shared_ptr<A> p(new A(10)); // 后面打印release A: 10
A *q = &a;
return 0;
}
返回值如下
release A: 10
release A: 5
可以看出:智能指针p被自动释放了, 而普通指针q却没有;
注意: release A:5 其实释放的是A a的内存;
下面实现了一个完整的shared_ptr类
template <class T>
class Smart_ptr {
private:
T* _ptr; // 原生指针
int* _count; // 引用计数
public:
// 基本的构造函数
Smart_ptr(T *ptr = nullptr): _ptr(ptr) { // 写构造函数,_count++;
cout << "基本构造" << endl;
if (_ptr)
_count = new int(1);
else
_count = new int(0);
}
// 拷贝构造, 此时传入的同样是一个Smart_ptr类指针
Smart_ptr(const Smart_ptr &ptr) {
cout << "拷贝构造" << endl;
if (this != &ptr) {
this -> _ptr = ptr._ptr;
this -> _count = ptr._count;
(*this->_count) ++;
}
}
// 重载=操作符
Smart_ptr operator=(const Smart_ptr &ptr) {
// a b指向的内容一样,不用管
cout << "赋值操作" << endl;
if (! ptr._ptr)
return nullptr;
if (this->_ptr == ptr._ptr)
return *this;
// a b不一样,需要进行赋值操作,此时需要对this原引用计数-1,如果为0需要释放
if (this->_ptr) {
(*this->_count) --;
if (!*this->_count) { // 释放原this指向的内存
delete this->_count;
delete this->_ptr;
}
}
// 下面进行赋值拷贝
this->_ptr = ptr._ptr;
this->_count = ptr._count;
(*this->_count)++;
return *this;
}
// 重载*操作符
T operator*(){
if (this->_ptr)
return *_ptr;
}
// 重载->操作符
T operator->(){
if (this->_ptr)
return *_ptr;
}
~Smart_ptr() {
(*this->_count)--;
if (!*this->_count) {
delete this->_ptr;
delete this->_count;
}
}
int use_count() {
return *_count;
}
};