欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 智能指针学习笔记

智能指针学习笔记

2025/12/2 7:15:35 来源:https://blog.csdn.net/weixin_42130300/article/details/142490054  浏览:    关键词:智能指针学习笔记

unique_ptr

依靠独占权方式控制。

使用方法如下:

#include <iostream>
#include <memory>class TestA
{public:TestA(int n): member(n){};void show() {std::cout << "init class, n: " << member << std::endl;}private:int member;
};void pass_by_value(std::unique_ptr<TestA> a) 
{std::cout << "pass by value \n";a->show();
}void print_by_ref(std::unique_ptr<TestA> &a)
{std::cout << "print by ref \n";a->show();a.reset();      // 清空指针
}void print_by_ref_const(const std::unique_ptr<TestA> &a)
{std::cout << "print by ref \n";a->show();// a.reset();   // const 引用,不可以修改值
}std::unique_ptr<TestA> return_by_value()
{std::cout << "return by value function \n";std::unique_ptr<TestA> local = std::make_unique<TestA>(6);return local;
}int main()
{// 构造方式1TestA *a_ptr = new TestA(1);std::unique_ptr<TestA> a_unique_ptr{a_ptr};a_unique_ptr->show();// 构造方式2std::unique_ptr<TestA> unique_ptr_02{new TestA(2)};unique_ptr_02->show();// 构造方式3std::unique_ptr<TestA> unique_ptr_03 = std::make_unique<TestA>(3);unique_ptr_03->show();// 函数传递值std::unique_ptr<TestA> unique_pass_by_value = std::make_unique<TestA>(4);pass_by_value(std::move(unique_pass_by_value));     // 转换为右值// 传递引用std::unique_ptr<TestA> unique_pass_by_ref = std::make_unique<TestA>(5);print_by_ref(unique_pass_by_ref);// 函数返回值std::unique_ptr<TestA> return_by_value_ptr{std::move(return_by_value())};return_by_value_ptr->show();return 0;
}

模拟实现原理:

	template<class T>class unique_ptr{public:// RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源// 保存资源unique_ptr(T* ptr):_ptr(ptr){}// 释放资源~unique_ptr(){delete _ptr;}unique_ptr(const unique_ptr<T>& up) = delete;unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;// 像指针一样T& operator*(){return *_ptr;}T* operator->(){return return _ptr;}T& operator[](size_t pos){return _ptr[pos];}private:T* _ptr;};


shared_ptr

使用方式如下:

#include <iostream>
#include <memory>
#include <string>class TestA
{public:TestA(int n, std::string name): member(n), m_name(name){};void show() {std::cout << "Init class, id: " << member << " name: " << m_name << std::endl;}void update_name(std::string name) {m_name = name;}private:int member;std::string m_name;
};void pass_by_value(std::shared_ptr<TestA> a)
{std::cout << "------------------------------------------------------------- \n";std::cout << "pass by value function \n";a->show();std::cout << "use count: " << a.use_count() << std::endl;std::cout << "------------------------------------------------------------- \n";
}void pass_by_ref(std::shared_ptr<TestA> &a)
{std::cout << "------------------------------------------------------------- \n";std::cout << "pass by ref function \n";a->show();std::cout << "use count: " << a.use_count() << std::endl;std::cout << "------------------------------------------------------------- \n";
}std::shared_ptr<TestA> get_share_ptr()
{std::shared_ptr<TestA> local = std::make_shared<TestA>(10, "local");return local;
}int main()
{// 构建方式1std::shared_ptr<TestA> ptr1 = std::make_shared<TestA>(1, "bobo");ptr1->show();// 查看引用计数std::cout << "use count: " << ptr1.use_count() << std::endl;// 赋值std::shared_ptr<TestA> ptr2 = ptr1;auto ptr3 = ptr1;std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;std::cout << "ptr2 use count: " << ptr2.use_count() << std::endl;std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;// 删除某一个指针观察引用计数ptr2 = nullptr;      // ptr2.reset();std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;// 因为共享某一块内存,可以观察值std::cout << "------------------------------------------------------------- \n";ptr1->update_name("tom");ptr1->show();ptr3->show();std::cout << "------------------------------------------------------------- \n";pass_by_value(ptr1);std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;std::cout << "------------------------------------------------------------- \n";pass_by_ref(ptr1);std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;std::cout << "------------------------------------------------------------- \n";std::shared_ptr<TestA> ptr4 = get_share_ptr();std::cout << "ptr4 use count: " << ptr4.use_count() << std::endl;std::cout << "Finished! \n";return 0;
}

模拟实现原理:

	template<class T>class shared_ptr{public:// RAII// 保存资源shared_ptr(T* ptr):_ptr(ptr), _pcount(new int(1)){}// 释放资源~shared_ptr(){Release();}shared_ptr(const shared_ptr<T>& sp):_ptr(sp._ptr), _pcount(sp._pcount){++(*_pcount);}void Release(){if (--(*_pcount) == 0){delete _pcount;delete _ptr;}}//sp1 = sp1;//sp1 = sp2;//sp2如果是sp1的拷贝呢?shared_ptr<T>& operator=(const shared_ptr<T>& sp){if (_ptr != sp._ptr)//资源地址不一样{Release();_pcount = sp._pcount;_ptr = sp._ptr;++(*_pcount);}return *this;}int use_count(){return *_pcount;}// 像指针一样T& operator*(){return *_ptr;}T* operator->(){return _ptr;}T& operator[](size_t pos){return _ptr[pos];}private:T* _ptr;int* _pcount;};

存在两个注意事项:

1. 关于int,成员变量的引用计数必须是int*。不可以直接是int,不然没有引用计数的作用。

2. 关于是否可以声明为静态成员。不可以,否则每一个相同类型的对象都共享该计数。

其他

1. 共享指针总体的使用来说是不线程安全的(构造和析构时才会改变引用计数,但是在访问资源时是不安全的)。可以对引用计数改变时加锁,或者将+或-操作改变为原子操作。

2. 循环引用。需要通过weak_ptr进行解决。

class Test 
{private:std::shared_ptr<Test> m_friend;     // 为了避免循环引用,改为weak_ptr即可
}

3. 不可以将shared_ptr转换为unique_ptr。 unique_ptr可以转换为shared_ptr,通过std::move。

参考资料:【C++11】智能指针_c++智能指针-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词