智能指针

智能指针

shared_ptr

操作方法

image-20230315194353315

操作实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "iostream"
#include "memory"

class myClass{
public:
int tem;
public:
myClass(){
tem=0;
}
myClass(int a):tem(a){}

};

int main()
{
//std::shared_ptr的初始化
//第一种使用以下方法
int *pInt=new int[]{1,2,3,4};
std::shared_ptr<int> sharedPtr(pInt,[](int* pInt1){
std::cout<<"delete[] pInt1"<<std::endl;
delete[] pInt1;
});
std::cout<<"sharedPtr.use_count():"<<sharedPtr.use_count()<<std::endl;
//1.1
std::shared_ptr<char> sharedPtr1(new char);
*sharedPtr1='c';
std::cout<<"*sharedPtr1= "<<*sharedPtr1<<std::endl;
std::cout<<"sharedPtr1.use_count():"<<sharedPtr1.use_count()<<std::endl;
//1.2
int intSize=0;
std::cout<<"intSize:";
std::cin>>intSize;
std::shared_ptr<int[]> sharedPtr2(new int[intSize],[](int* pInt1){
std::cout<<"this lambda"<<std::endl;
delete[] pInt1;
});
std::cout<<"sharedPtr2.use_count():"<<sharedPtr2.use_count()<<std::endl;//输出1
for (int i = 0; i < intSize; ++i) {
sharedPtr2[i]=i;
}
for (int i = 0; i < intSize; ++i) {
std::cout<<"sharedPtr2:"<<sharedPtr2[i]<<" ";
}
std::cout<<std::endl;
//1.3 //无参构造
std::shared_ptr<char> sharedPtr3;//无参构造1
std::cout<<"sharedPtr3.use_count():"<<sharedPtr3.use_count()<<std::endl;
//1.4 //直接负值
sharedPtr3=sharedPtr1;

//第二种通过拷贝构造和移动构造
//2.1 //通过move
sharedPtr3= std::move(sharedPtr1);//通过move实现资源的转移

//第三种 通过make_shared
//3.1
/*
* explain: use a fundamental type
*/
std::shared_ptr<int > sharedPtr4=std::make_shared<int>(520);//520是对该堆内存的初始化
std::cout<<"sharedPtr4:"<<*sharedPtr4<<std::endl;
/*
* explain: use a class
*/

std::shared_ptr<myClass> sharedPtr5= std::make_shared<myClass>(1314);
std::cout<<"sharedPtr5:"<<sharedPtr5.get()->tem<< std::endl;//get返回普通变量的指针

sharedPtr5= std::make_shared<myClass>(244);
std::cout<<"sharedPtr5:"<<sharedPtr5.get()->tem<< std::endl;//get返回普通变量的指针
std::cout<<"sharedPtr5.use_count():"<<sharedPtr5.use_count()<<std::endl;

//第四种 //reseet()
//reset的两个功能:1.接触该内存的控制 2.接触该内存的控制,并控制其他的内存
//4.1 接触控制
sharedPtr5.reset();
std::cout<<"sharedPtr5:"<<sharedPtr5.use_count()<< std::endl;//get返回普通变量的指针

sharedPtr2.reset(new int{1});//注意此处,reset的地址应该和原来管理的一样
sharedPtr5.reset(new myClass{8989});
std::cout<<"sharedPtr5.use_count():"<<sharedPtr5.use_count()<< std::endl;//get返回普通变量的指针
std::cout<<"sharedPtr5:"<<sharedPtr5.get()->tem<< std::endl;//get返回普通变量的指针

//操作智能指针
//删除器函数
//lambda
std::shared_ptr<int[]> sharedPtr6(new int[2]{1,3},[](int* pInt1){
std::cout<<"this is deleting sharedPtr6"<<std::endl;
delete[] pInt1;
});
std::cout<<"sharedPtr6:"<<*sharedPtr6.get()<<" "<<*(sharedPtr6.get()+1)<<std::endl;
//c++自带的
std::shared_ptr<int[]> sharedPtr7(new int[]{9,6,9,2,4,4},std::default_delete<int[]>());
for (int i = 0; i < 6; ++i) {
std::cout<<*(sharedPtr7.get()+i)<<" ";
}
std::cout<<std::endl;
return 0;
}

unique_ptrc

操作实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
#include<memory>
#include "functional"

int main()
{
//一,初始化
//1.1 使用构造函数
std::unique_ptr<int > uniquePtr(new int{25});
std::cout<<*uniquePtr<<std::endl;
*uniquePtr.get()=100;
std::cout<<*uniquePtr<<std::endl;
std::cout<<uniquePtr.get()<< std::endl;
//1.2 使用移动构造
std::unique_ptr<int> uniquePtr1= std::move(uniquePtr);
std::cout<<*uniquePtr1<<std::endl;

//1.3 使用reset
std::cout<<uniquePtr1.get()<< std::endl;
uniquePtr1.reset();
std::cout<<uniquePtr1.get()<< std::endl;
uniquePtr1.reset(new int {959});
std::cout<<uniquePtr1.get()<< std::endl;
uniquePtr.reset(new int{2});
std::cout<<uniquePtr.get()<< std::endl;

//unique_ptr 删除器
//函数指针实例 lambda在没有捕获的时候,可以看成函数指针
/*using funcPtr=void(*)(int*);*/
std::unique_ptr<int[],void(*)(int*)> uniquePtr2(new int[]{0,1},[](int * pInt){
std::cout<<"delete uniquePtr2"<<std::endl;
delete[] pInt;
});
uniquePtr2[0]=244;
std::cout<<"uniquePtr2[0]:"<<uniquePtr2[0]<<std::endl;
std::cout<<"uniquePtr2[1]:"<<uniquePtr2[1]<<std::endl;

//仿函数实例 lambda在有捕获的时候,只能看成函数仿函数
std::unique_ptr<int,std::function<void(int*)>> uniquePtr3(new int{244},[&uniquePtr2](int* pInt){
uniquePtr2[1]=6;
std::cout<<"delete uniquePtr3"<<std::endl;
delete pInt;
});
uniquePtr3.reset();
std::cout<<"uniquePtr2[1]:"<<uniquePtr2[1]<<std::endl;


//std::unique_ptr 类型可以对数组指针自动管理 不需要想shared的那样的指定删除器函数

return 0;
}

weak_ptr

  1. 初始化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int main()
    {
    //weak_ptr的初始化
    std::shared_ptr<int> sharedPtr(new int{233});
    //无参构造
    std::weak_ptr<int> weakPtr;
    //拷贝构造
    std::weak_ptr<int> weakPtr1(weakPtr);
    //通过shared_ptr
    std::weak_ptr<int> weakPtr2(sharedPtr);
    //使用=
    std::weak_ptr<int> weakPtr3;
    weakPtr3=weakPtr2;
    std::cout<<"weakPtr3.use_count:"<<weakPtr3.use_count()<<std::endl;


    return 0;
    }
  2. expired 判断所指的对象是否析构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main(){
    std::shared_ptr<int> sharedPtr(new int{244});
    std::weak_ptr<int>weakPtr(sharedPtr);
    std::cout<<"weakPtr.use_count():"<<weakPtr.use_count()<<std::endl;

    std::cout<<"weakPtr.expired():"<<(weakPtr.expired()?"is":"not")<< std::endl;

    sharedPtr.reset();
    std::cout<<"weakPtr.use_count():"<<weakPtr.use_count()<<std::endl;
    std::cout<<"weakPtr.expired():"<<(weakPtr.expired()?"is":"not")<< std::endl;

    return 0;
    }

注意事项

  1. 不能使用同一个堆内存初始化智能指针

    ![image-20230319185006853](C:\Users\12414\OneDrive - cuit.edu.cn\桌面\智能指针.assets\image-20230319185006853.png)

    但是可以使用”=” 进行赋值操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Test* test=new Test;
    std::shared_ptr<Test>sharedPtr(test);
    std::shared_ptr sharedPtr1=sharedPtr;
    std::cout<<"sharedPtr.use_count():"<<sharedPtr.use_count()<<std::endl;
    std::shared_ptr<Test> sharedPtr2= std::move(sharedPtr);
    std::cout<<"sharedPtr2.use_count():"<<sharedPtr2.use_count()<<std::endl;
    std::shared_ptr<Test> sharedPtr3=sharedPtr;
    std::cout<<"sharedPtr3.use_count():"<<sharedPtr3.use_count()<<std::endl;
    //此时sharedPtr已经move,所以结果为0
  2. 对智能指针使用’.’操作的智能指针的api,如果使用’->’操作的是,对应的类的成员方法

  3. 正确的返回this

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    struct Test:public std::enable_shared_from_this<Test>{
    Test(){
    std::cout<<"Test()"<<std::endl;
    }
    ~Test(){
    std::cout<<"~Test()"<<std::endl;
    }
    std::shared_ptr<Test> getSharedPtr(){
    return shared_from_this();
    }
    };

    int main(){
    std::shared_ptr<Test> sharedPtr(new Test);
    std::cout<<"sharedPtr.use_count():"<<sharedPtr.use_count()<<std::endl;
    std::shared_ptr<Test> sharedPtr1=sharedPtr->getSharedPtr();
    std::cout<<"sharedPtr1.use_count():"<<sharedPtr1.use_count()<<std::endl;

    return 0;
    }
  4. 共享智能指针不能循环引用


智能指针
https://tsy244.github.io/2023/04/11/cpp/智能指针/
Author
August Rosenberg
Posted on
April 11, 2023
Licensed under