• C++文档阅读笔记-Smart Pointers in C++ and How to Use Them


    此篇博文,介绍了C++中智能指针,为何要使用智能指针,以及如何去用。

    指针可使得程序直接访问堆区内存。通过指针,可以直接对原始资源进行修改,也就是说指针指向的就是一手资源。

    Problems with Normal Pointers

    如下代码:

    1. #include
    2. using namespace std;
    3. class Rectangle {
    4. private:
    5. int length;
    6. int breadth;
    7. };
    8. void fun()
    9. {
    10. // By taking a pointer p and
    11. // dynamically creating object
    12. // of class rectangle
    13. Rectangle* p = new Rectangle();
    14. }
    15. int main()
    16. {
    17. // Infinite Loop
    18. while (1) {
    19. fun();
    20. }
    21. }

    上面代码的fun()函数中,创建了Rectangle对象,Rectangle对象包含2个int型成员,分别表示长和宽。当这个函数结束后,指针p并没有被销毁,原因是没有调用delete p,这就造成堆区内存浪费。C++程序有个主旨就是“我们不需变量,我们需要内存”。

    在main()函数中,fun()函数被无止境的调用,这也就造成了,无止境的创建p,但不去释放p的资源,导致这块内存程序员无法使用,这就叫内存泄漏。C++11为了解决这一问题,提出了智能指针。

    Introduction of Smart Pointers

    每一个C++程序员都会不自觉的犯一种错,那就是创建的指针,忘记手动释放,最后导致程序崩溃。像Java、C#都有自己的垃圾回收机制,去回收不用了的堆区内存,避免出现内存泄漏的问题。C++11也推出了自己的一套机制,那就是智能指针。如果程序员想销毁一个对象时,不需要再调用delete方法了,智能指针会自动将其销毁。

    其实智能指针就是一个被封装了的类,封装了一些操作符,如*、->。操作智能指针就和普通指针一样。唯一的区别就是普通指针需要自己手动回收资源。

    当智能指针在指定的生命周期结束后,会自动释放内存。

    智能指针的封装,可以参考如下代码:

    1. #include
    2. using namespace std;
    3. class SmartPtr {
    4. int* ptr; // Actual pointer
    5. public:
    6. // Constructor: Refer https:// www.geeksforgeeks.org/g-fact-93/
    7. // for use of explicit keyword
    8. explicit SmartPtr(int* p = NULL) { ptr = p; }
    9. // Destructor
    10. ~SmartPtr() { delete (ptr); }
    11. // Overloading dereferencing operator
    12. int& operator*() { return *ptr; }
    13. };
    14. int main()
    15. {
    16. SmartPtr ptr(new int());
    17. *ptr = 20;
    18. cout << *ptr;
    19. // We don't need to call delete ptr: when the object
    20. // ptr goes out of scope, the destructor for it is automatically
    21. // called and destructor does delete ptr.
    22. return 0;
    23. }

    输出为:

    20

    上面的代码仅仅适用于int类型,如果需要创建任意类型的对象,就需要使用Template,模板编程如下代码:

    1. #include
    2. using namespace std;
    3. // A generic smart pointer class
    4. template <class T>
    5. class SmartPtr {
    6. T* ptr; // Actual pointer
    7. public:
    8. // Constructor
    9. explicit SmartPtr(T* p = NULL) { ptr = p; }
    10. // Destructor
    11. ~SmartPtr() { delete (ptr); }
    12. // Overloading dereferencing operator
    13. T& operator*() { return *ptr; }
    14. // Overloading arrow operator so that
    15. // members of T can be accessed
    16. // like a pointer (useful if T represents
    17. // a class or struct or union type)
    18. T* operator->() { return ptr; }
    19. };
    20. int main()
    21. {
    22. SmartPtr<int> ptr(new int());
    23. *ptr = 20;
    24. cout << *ptr;
    25. return 0;
    26. }

    输出如下:

    20

    注意:智能指针一般用于管理资源,比如handles和Sockets,如文件句柄、TCP套接字。

    Types of Smart Pointers

    1.unique_ptr

    unique_ptr存储了单独的一个指针。可以把当前智能指针的对象移除,添加新的对象。如下图所示,unique_pointer P1指向了一个object,只有将P1中的object移除后P2才能指向object。

    代码如下:

    1. #include
    2. using namespace std;
    3. #include
    4. class Rectangle {
    5. int length;
    6. int breadth;
    7. public:
    8. Rectangle(int l, int b){
    9. length = l;
    10. breadth = b;
    11. }
    12. int area(){
    13. return length * breadth;
    14. }
    15. };
    16. int main(){
    17. unique_ptr P1(new Rectangle(10, 5));
    18. cout << P1->area() << endl; // This'll print 50
    19. // unique_ptr P2(P1);
    20. unique_ptr P2;
    21. P2 = move(P1);
    22. // This'll print 50
    23. cout << P2->area() << endl;
    24. // cout<area()<
    25. return 0;
    26. }

    输出:

    1. 50
    2. 50

     

    2.shared_ptr

    多个shared_ptr可以在同一时间指向1个object,并且提供了计数功能,记录这个对象被多少个shared_ptr指向。调用的方法是use_count()。

    代码如下:

    1. #include
    2. using namespace std;
    3. #include
    4. class Rectangle {
    5. int length;
    6. int breadth;
    7. public:
    8. Rectangle(int l, int b)
    9. {
    10. length = l;
    11. breadth = b;
    12. }
    13. int area()
    14. {
    15. return length * breadth;
    16. }
    17. };
    18. int main()
    19. {
    20. shared_ptr P1(new Rectangle(10, 5));
    21. // This'll print 50
    22. cout << P1->area() << endl;
    23. shared_ptr P2;
    24. P2 = P1;
    25. // This'll print 50
    26. cout << P2->area() << endl;
    27. // This'll now not give an error,
    28. cout << P1->area() << endl;
    29. // This'll also print 50 now
    30. // This'll print 2 as Reference Counter is 2
    31. cout << P1.use_count() << endl;
    32. return 0;
    33. }

     输出:

    1. 50
    2. 50
    3. 50
    4. 2

    3.weak_ptr

    这个weak_ptr就是shared_ptr的简化版,就是删除了其指向计数的功能。

    C++提供的智能指针有4个分别是:auto_ptr、unique_ptr、shared_ptr、weak_ptr

    估计是auto_ptr太简单了,所以才没有相关介绍。

     

  • 相关阅读:
    简单版 快速掌握实践 SpringBoot继承Shiro框架详解!
    【At Coder begin 345】[D - Tiling] 回溯
    C语言操作符例题
    C# RulesEngine 规则引擎:从入门到看懵
    Kubernetes 的服务网格
    潘多拉 IOT 开发板学习(RT-Thread)—— 实验1 LED 闪烁实验(学习笔记)
    归并排序 Merge Sort
    Tomcat多实例、负载均衡、动静分离
    leetcode.1769 移动所有球到每个盒子所需的最小操作数
    UML之类图
  • 原文地址:https://blog.csdn.net/qq78442761/article/details/126577587