一、原因
动态内存的管理需要程序员手动申请和释放,动态内存的分配和释放用new和delete运算符来完成,如果new和delete的操作次数不一致,则会造成内存泄漏、二次释放等问题,为了更加方便和安全地使用动态内存,c++11引入了智能指针的概念
二、概念
智能指针是指能够自动释放所指向的对象的指针,它本质上不是一个指针,而是封装了一个普通指针的类对象,其设计思想来源于“RAII”,即“资源获取就是初始化”,通过一个对象,在其构造时获取资源,在其生命周期结束自动调用析构函数释放所指向的对象,使用智能指针需要include<memory>头文件</memory>
三、分类
1.auto_ptr
同一时刻只有一个指针指向实际对象,不支持拷贝和赋值操作
2.unique_ptr
同一时刻只有一个unique_prt指向一个给定对象,也不支持拷贝和赋值操作,可以使用move转移所有权
unique_ptr<int> p3 = std::move(p1); //现在那块内存归p3所有, p1成为无效的指针
3.shared_ptr
多个指针可以指向同一个对象,每个shared_ptr都有一个关联的计数器,用来表示所指向的对象被引用的次数,支持赋值和拷贝,当计数器为0时对象会被释放(可以使用make_shared函数初始化。不能将指针直接赋值给一个智能指针,因为一个是类,一个是指针)
4.weaked_ptr
一种不控制所指向对象生存期的智能指针,它指向一个由shared_ptr管理的对象,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向对象,对象还是会被释放。
int main() {
{
std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
std::cout << sh_ptr.use_count() << std::endl;
std::cout << *sh_ptr<< std::endl; //获得指针的值
std::weak_ptr<int> wp(sh_ptr);//弱指针可以观测资源的使用情况
std::cout << wp.use_count() << std::endl;
if(!wp.expired()){ //lock()函数,从被观测的shared_ptr获得一个可用的
std::shared_ptr<int> sh_ptr2 = wp.lock(); //shared_ptr对象, 从而操作资源
*sh_ptr = 100;
std::cout << wp.use_count() << std::endl;
}
}
//delete memory
}四、实现shared_ptr
template<typename T>
class sharedptr {
public:
//构造函数
sharedptr(T *ptr):_ptr(ptr),_cnt(new int(1)) {
cout << "构造" << endl;
}
//拷贝构造
sharedptr(sharedptr<T> sp):_ptr(sp._ptr),_cnt(sp._cnt){
cout << "拷贝构造" << endl;
++(*_cnt);
}
//赋值操作运算符
sharedptr<T> operator=(sharedptr<T> sp) {
cout << "赋值操作运算符" << endl;
if (_ptr != sp._ptr) {
if (--(*_cnt) == 0) {//计数器为0,则释放指针指向的对象
delete _ptr;
delete _cnt;
}
_ptr = sp._ptr;
_cnt = sp._cnt;
++(*_cnt);
}
return *this;
}
T * operator->() {
return _ptr;
}
T& operator*() {
return *_ptr;
}
int getcnt() {
return *_cnt;
}
~sharedptr(){
cout << "析构" << endl;
if (--(*cnt) == 0) {
delete _ptr;
_ptr = nullptr;
delete _cnt;
_cnt = nullptr;
}
}
private:
int *_cnt;
T *_ptr;
};


京公网安备 11010502036488号