深入学习c++--智能指针(一) shared_ptr

时间:2021-06-21 16:18:12

1. 几种智能指针

1. auto_ptr: c++11中推荐不使用他(放弃)

2. shared_ptr: 拥有共享对象所有权语义的智能指针

3. unique_ptr: 拥有独有对象所有权语义的智能指针

4. weaked_ptr: 到 std::shared_ptr 所管理对象的弱引用

1.1 shared_ptr

参考:https://zh.cppreference.com/w/cpp/memory/shared_ptr

std::shared_ptr 是通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可占有同一对象。下列情况之一出现时销毁对象并解分配其内存:

  • 最后剩下的占有对象的 shared_ptr 被销毁;
  • 最后剩下的占有对象的 shared_ptr 被通过 operator= 或 reset() 赋值为另一指针。
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex> class Object
{
public:
Object(int id) : m_id(id) {
std::cout << "init obj " << m_id << std::endl;
}
~Object() {
std::cout << "bye bye " << m_id << std::endl;
}
int id() const {
return m_id;
}
private:
int m_id;
}; typedef std::shared_ptr<Object> ObjectPtr; void print(ObjectPtr obj);
void printRef(const ObjectPtr& obj); void interfaceOfSharedPtr()
{
ObjectPtr null;
std::cout << "ref count is " << null.use_count() << std::endl; // ObjectPtr obj(new Object());
std::cout << "ref count is " << obj.use_count() << std::endl; // ObjectPtr obj2(obj);
std::cout << "ref count is " << obj.use_count() << std::endl; // ObjectPtr obj3 = obj;
std::cout << "ref count is " << obj.use_count() << std::endl; // obj2.reset(); // 不需要了
//obj2 = nullptr; // c++11写法
std::cout << "ref count is " << obj.use_count() << std::endl; // ObjectPtr obj4;
obj3.swap(obj4);
//std::swap(obj3, obj4); // 本身管理资源,引用数没有变化
std::cout << "ref count is " << obj.use_count() << std::endl; // auto p = obj.get();
if (p)
{
std::cout << "id is " << p->id() << std::endl;
} if (obj)
{
std::cout << "p id is " << obj->id() << std::endl; // operator ->
std::cout << "ref id is " << (*obj).id() << std::endl; // operator *
} obj4 = nullptr;
// if (obj.unique()) //效率更高
// if (obj.use_count() == 1) // 会有效率损失 std::cout << "only one hold ptr " << obj.unique() << std::endl;
// 值传入
print(obj);
std::cout << "ref count is " << obj.use_count() << std::endl; // 引用传入, 推荐
printRef(obj);
} void print(ObjectPtr obj) // 值传入,会临时改变引用数量+1
{
std::cout << "count " << obj.use_count() << " id " << obj->id()
<< std::endl; //
} void printRef(const ObjectPtr& obj) // 引用传递不会改变引用数量
{
std::cout << "ref count " << obj.use_count() << " id " << obj->id()
<< std::endl; //
} void deleteOfObject(Object* obj)
{
if (obj) {
std::cout << "delete obj " << obj->id() << std::endl;
delete obj;
}
} void useDeleter()
{
// 管理 裸指针 和 处理这个指针的函数 -- 可以管理应用delete资源,也可以管理其他类似资源
ObjectPtr obj(new Object(), deleteOfObject);
ObjectPtr obj2 = obj;
} int main()
{ interfaceOfSharedPtr(); return ;
}
ref count is
init obj
ref count is
ref count is
ref count is
ref count is
ref count is
id is
p id is
ref id is
only one hold ptr
count id
ref count is
ref count id
bye bye