• 27 智能指针


    1 内存泄漏问题

    • 动态申请堆空间,用完后不归还

    • C++ 语言中没有垃圾回收机制

    • 指针无法控制所指堆空间的生命周期

    • 示例1:内存泄漏

      • Demo

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        // 测试类
        class Test
        {
            int i;
        public:
            Test(int i) {
                this->i = i;
            }
            int value() {
                return i;
            }
            ~Test() {
            }
        };
        
        int main()
        {
            for(int i = 0; i < 5; i++) {
                Test* p = new Test(i);
                cout << p->value() << endl; 
            }
            
            return 0;
        }
        
      • 编译运行

        0
        1
        2
        3
        4
        
      • 存在内存泄漏:24 行定义的局部变量 pfor 循环结束后会自动销毁,但其所指向的堆空间并没有消失,那么就没有人没有使用这块堆空间,造成内存泄漏

    • 需要什么?

      • 需要一个特殊的指针
      • 指针生命周期结束时主动释放堆空间 ---> 避免内存空间忘记释放的问题
      • 一片堆空间最多只能由一个指针标识 ---> 避免一块内存空间多次释放的问题
      • 杜绝指针运算和指针比较 ---> 避免指针越界,防止野指针的出现

    2 智能指针

    • 解决方案

      • 重载指针特征操作符(->*
      • 只能通过类的成员函数重载
      • 重载函数不能使用参数
      • 只能定义一个重载函数
    • 示例2:智能指针

      • Demo

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        // 测试类
        class Test
        {
            int i;
        public:
            Test(int i) {
                cout << "Test(int i)" << endl;
                this->i = i;
            }
            int value() {
                return i;
            }
            ~Test() {
                cout << "~Test()" << endl;
            }
        };
        
        
        // 智能指针类
        class Pointer
        {
            Test* mp;
        public:
            Pointer(Test* p = NULL) {
                mp = p;
            }
            
            Pointer(const Pointer& obj) {
                // 不需要释放成员变量所指向堆空间,因为是构造函数,mp还是一个野指针,不能delete
                mp = obj.mp;
                const_cast<Pointer&>(obj).mp = NULL;
            }
            
            Pointer& operator = (const Pointer& obj) {
                if( this != &obj ) {
                    // 首先释放“被赋值的对象”的成员所指向的堆空间
                    delete mp;
                    mp = obj.mp;
                    const_cast<Pointer&>(obj).mp = NULL;
                }    
                return *this;
            }
            
            Test* operator -> () {
                return mp;
            }
            
            Test& operator * () {
                return *mp;
            }
            
            bool isNull() {
                return (mp == NULL);
            }
            
            ~Pointer() {
                delete mp;
            }
        };
        
        int main()
        {
            Pointer p1 = new Test(0);
            
            cout << p1->value() << endl;
            
            Pointer p2 = p1;
            
            cout << p1.isNull() << endl;
            
            cout << p2->value() << endl;
            
            return 0;
        }
        
      • 编译运行

        Test(int i)
        0
        1
        0
        ~Test()
        
    • 智能指针使用规则:只能用来指向堆空间中的对象或者变量

  • 相关阅读:
    三范式最简单最易记的解释
    Mysql添加用户错误:ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value解决方法
    mysql体系结构管理
    mysql的简单操作
    flush privileges刷新MySQL的系统权限相关表
    二进制安装mysql
    扩展一台mysql-5.6.40
    mysql5.6.40部署过程
    三剑客-awk
    三剑客-sed
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13903870.html
Copyright © 2020-2023  润新知