• C++构造函数和析构函数


    C++构造函数和析构函数

    0. 定义

    构造函数:创建对象时为对象的成员进行初始化

    析构函数: 在对象销毁前执行清理工作

    特点:

    • 构造函数和析构函数,如果没有手动提供,编译器会提供一个默认的,默认的构造函数、默认拷贝函数和析构函数中,什么都不做,编译器会强制执行;

                  构造函数的调用规则:
                                        如果用户定义了普通的构造函数(非拷贝构造),C++不会提供默认无参构造,但会提供默认拷贝构造函数;
                                        如果用户定义了拷贝构造函数,C++不会提供任何默认构造函数;
      
      • 1
      • 2
      • 3
    • 如果我们提供了构造函数,系统将不会提供任何无参默认构造函数;

    • 构造函数和析构函数下在public权限下;

    • 构造函数:

      1. 构造函数和类名相同;

      2. 没有返回值,不用写void;

      3. 允许多个参数,可以重载;

    • 析构函数:

      1. 构造函数和类名相同,前面加上~;

      2. 没有返回值,不用写void;

      3. 无参数,不支持重载;

    1. 构造函数及重载构造函数

    class Student
    {
    public:
            string m_Name;
            int m_Age;
    
            // 构造函数
            Student()
            {
                    m_Name = "";
                    m_Age = 0;
                    cout << "构造函数执行了" << endl;
            }
            // 重载带参数的构造函数
            Student(string name, int age)
            {
                    m_Name = name;
                    m_Age = age;
                    cout << "有参数构造函数执行了" << endl;
            }
            // 析构函数
            ~Student()
            {
                    cout << "析构函数执行了" << endl;
            }
    };
    
    int main()
    {
            Student s;
            cout << s.m_Name << endl;
            cout << s.m_Age << endl;
    }
    
    • 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

    2. 构造函数的分类

    有无参数分:

    • 无参构造(默认构造);
    • 有参构造;

    类型分:

    • 普通构造;
    • 拷贝构造;
    class Person
    {
    public:
            int m_Age;
    
            // 无参构造函数
            Person()
            {
                    m_Age = 0;
                    cout << "无参构造函数执行了" << endl;
            }
            // 重载有参数构造函数
            Person(int age)
            {
                    m_Age = age;
                    cout << "有参构造函数执行了" << endl;
            }
            // 拷贝构造函数
            Person(const Person &p)
            {
                    m_Age = p.m_Age;
                    cout << "拷贝构造函数执行了" << endl;
            }
            // 析构函数
            ~Person()
            {
                    cout << "析构函数执行了" << endl;
            }
    };
    
    int main()
    {
            // 构造函数的调用:显示调用、隐式调用
    
            // 显示调用:
            Person p = Person();
            Person p1 = Person(20);
            cout << p1.m_Age << endl;
            Person p4 = Person(p);
            cout << p4.m_Age << endl;
    
            // 隐式调用:
            Person p2;
            // Person p2(); 隐式调用无参调用不能加上括号
            Person p3(30);
            cout << p3.m_Age << endl;
            Person p5(p3);
    
            // 匿名对象,本行执行完立即释放(析构);不能使用拷贝构造函数初始化匿名对象
            // Person();
    
            // 隐式转换法:
            Person p6 = 10; // 编译器会转换成 Person p6 = Person(10);
            Person p7 = p6;
    
            // 初始化列表:
            Person p8 = {};
            Person p9 = {15};
            Person p10{25};
    }
    
    • 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

    3. 拷贝构造函数时机

    • 用一个对象初始化另一个对象;
    • 对象以值传递的方式传递给函数参数;
    • 局部对象以值传递的方式从函数返回
    class Person
    {
    public:
            int m_Age;
    
            Person()
            {
                    m_Age = 0;
                    cout << "无参构造函数执行了" << endl;
            }
            Person(int age)
            {
                    m_Age = age;
                    cout << "有参构造函数执行了" << endl;
            }
            Person(const Person &p)
            {
                    m_Age = p.m_Age;
                    cout << "拷贝构造函数执行了" << endl;
            }
            // 析构函数
            ~Person()
            {
                    cout << "析构函数执行了" << endl;
            }
    };
    void doWork(Person p) // Person p = p1;
    {
    }
    Person doWork1()
    {
            Person p(30);
            return p;
    }
    int main()
    {
            // 1. 用一个对象初始化另一个对象
            Person p1(10);
            Person p2(p1);
            // Person p3 = Person(p1);
            // Person p4 = p1;
            // Person p5 = {p1};
    
            // 2. 对象以值传递的方式传递给函数参数
            // doWork(p1);
    
            // 3. 局部对象以值传递的方式从函数返回
            // 编译器采用了一种优化 RVO(Return Value Optimization) Release - NRVO
            Person p6 = doWork1();
    }
    
    • 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
  • 相关阅读:
    当Java遇上泛型:类型安全的魔法之旅
    Apache简介与安装
    SwiftUI调用相机拍照
    python+pytest接口自动化之日志管理模块loguru简介
    ElasticSearch 学习(docker,传统方式安装、安装遇到的问题解决,)
    2022 OpenCV AI 竞赛来啦!详细介绍Spatial AI赛道!
    【LeetCode刷题日志】189.轮转数组
    python异步日志库loguru
    MOOC 大数据Note
    5G/4G外置型无线通信模块
  • 原文地址:https://blog.csdn.net/m0_56077202/article/details/125596009