设为首页 加入收藏

TOP

C++11 智能指针 shared_ptr(一)
2023-07-23 13:38:16 】 浏览:128
Tags:能指针 shared_ptr

C++11 智能指针 shared_ptr

Written on 2023-01-16

个人学习智能指针记录合集:

std::shared_ptr 共享智能指针,也被称为计数智能指针。

共享智能指针会记录有多少个共享智能指针指向同一个对象,当这个数为 0 的时候,程序自动的默认释放(析构)这个对象,记录有多少个的这个方法叫做引用计数

共享智能指针可以有多个共享智能指针同时管理同一个对象。

举个栗子

普通指针管理

#include <iostream>
#include <memory>
using namespace std;

class Person{
public: 
    Person(){ cout << "Constructor: person's age = " << m_age << endl; }
    Person(int age) : m_age(age){ cout << "Constructor: person's age = " << m_age << endl; }
    ~Person(){ cout << "Destructor: person's age = " << m_age << endl; }
    void getAge(){ cout << "Person's age = " << m_age << endl; }
private:
    int m_age = 0; 
}; 

int main()
{
    {
        Person *p = new Person(18);
    }

    cout << endl << "Before return" << endl;
    return 0;
}
/** 输出:
Constructor: person's age = 18

Before return

**/

依输出可见,p指向的对象并没有被析构,因为并没有析构函数中的打印,这造成了内存泄漏。

shared_ptr智能指针管理

// ...
int main()
{
    {
        shared_ptr<Person> sPtr1 {new Person(18)};
    }

    cout << endl << "Before return" << endl;
    return 0;
}
/** 输出:
Constructor: person's age = 18
Destructor: person's age = 18

Before return

**/

依输出可见,离开了程序块的作用域后,析构函数中的打印体现出来了,sPtr1管理的对象自动的被析构了。

获取引用计数

long use_count() const noexcept;

shared_ptrnullptr 时,返回为 0。

初始化

创建空管理的 shared_ptr

constexpr shared_ptr() noexcept;
constexpr shared_ptr(std::nullptr_t) noexcept;
  • std::nullptr_t:空指针nullptr

创建对非数组对象和数组对象管理的 shared_ptr

template< class Y >
explicit shared_ptr( Y* ptr );
  • Y:动态分配的对象的类型
// ...
int main()
{
    shared_ptr<int> sPtr1; // 创建空管理的shared_ptr
    cout << "sPtr1 use count = " << sPtr1.use_count() << endl;
    
    shared_ptr<int> sPtr2(nullptr); // 创建空管理的shared_ptr
    cout << "sPtr2 use count = " << sPtr2.use_count() << endl;
    
    shared_ptr<int> sPtr3(new int(100)); // 创建对非数组对象管理的shared_ptr
    cout << "sPtr3 use count = " << sPtr3.use_count() << endl;
    
    shared_ptr<int> sPtr4(new int[10]); // 创建对数组对象管理的shared_ptr
    cout << "sPtr4 use count = " << sPtr4.use_count();
    return 0;
}
/** 输出:
sPtr1 use count = 0
sPtr2 use count = 0
sPtr3 use count = 1
sPtr4 use count = 1
**/

解释:
sPtr1sPtr2都为nullptr,故引用计数都为 0;
sPtr3sPtr4所管理的对象,都只有一个 shared_ptr 管理,故引用计数都为 1。

创建指定删除器的 shared_ptr

template< class Y, class Deleter >
shared_ptr( Y* ptr, Deleter d );

template< class Deleter >
shared_ptr( std::nullptr_t ptr, Deleter d );

template< class Y, class Deleter, class Alloc >
shared_ptr( Y* ptr, Deleter d, Alloc alloc );

template< class Deleter, class Alloc >
shared_ptr( std::nullptr_t ptr, Deleter d, Alloc alloc );
  • Deleter:删除器,在引用计数为 0 时,shared_ptr 会自动的执行删除器
  • Alloc:分配器(Allocator)
  1. 默认删除器:默认对指向的内存地址进行释放,即析构掉这块地址的内容
    1. 非数组类型,以 delete ptr 为默认删除器
    2. 数组类型,以 delete[] ptr 为默认删除器
  2. 指定删除器:能够自行指定引用计数为 0 时,要做什么,比如有些场景不需要对指向的内存进行释放,比如关闭指向文件,关闭指向套接字
    1. 指定删除器的函数结构:
      void deletePtr(T* p){ ... }
      
    2. 也可使用 Lambda表达式

例,对于文件的使用场景,不是直接delete文件,而是关闭文件:

// ...
void closeFile(FILE* fp) 
{
    if (fp == nullptr) return;
    fclose(fp);
    cout << "File closed" << endl;
}
int main() 
{
    FILE* fp = fop
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇P1005 [NOIP2007 提高组] 矩阵取.. 下一篇CF1779C Least Prefix Sum 题解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目