• C++核心(八)构造和析构


    构造和析构函数
    构造函数:完成对象初始化工作
    析构函数:完成对象清理工作
    (1)构造函数语法:
    1)函数名和类名同
    2)函数的参数可以不同,可以重载
    3)程序在调用对象的时候会自动构造,无须手动调用,而且只会调用一次
    4)构造函数没有返回值也不写void

    (2)析构函数语法:
    1)析构函数,没有返回值,也不写void
    2)函数名称和类名相同,在前面加~
    3)析构函数不可以有参数,因此不可以发生重载
    4)程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次

    注意:先创建的对象后清理
    例子:

    #include<iostream>
    using namespace std;
    class test
    {
    
        private:
            int number; 
        public:
        	test(int number)
        {
            this->number=number;
            cout<<"number="<<number<<endl;
      	 }
        	~test()
        {
          	 cout<<"析构成功"<<this->number<<endl;
      	 }
    };
    
    void test()
    {
        class test t(1);
        class test t1(2);
    }
    int main()
    {
        test();
    }
    打印结果:number=1
    		 number=2
    		 析构成功2
    		 析构成功1
    
    • 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
    构造函数的两种分类:
    1)按有无参数分:有参构造和无参构造
    2)按类型分:普通构造和拷贝构造
    
    三种调用方式:
    1)括号法
    2)显式法
    3)隐式转换法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    #include<iostream>
    using namespace std;
    class person
    {
        public:
            person(const person &p)//拷贝构造函数
        {
            this->age=p.age;
            this->sex=p.sex;
        }
            person(int age,int sex)
        {
            this->age=age;
            this->sex=sex;
        }
            void get_age_sex()
        {
                cout<<age<<endl;
                cout<<sex<<endl;
        }
            person()
        {
    
        }
           
        private:
            int age;
            int sex;
    };
    void test()//调用
    {
        //1.括号法
        person p;//调用默认构造函数时,不要加(),不然编译器会认为在声明一个函数
        person p1(10,2);
        person p2(p1);
        p2.get_age_sex();   
    
        //显示法
        person x_p;
        person x_p1=person(10,2);
        person x_p2=person(x_p1); 
        //person(10,2)匿名对象,特点:当前行执行结束后,系统会立即回收匿名对象
        //不要利用拷贝构造函数来初始化匿名对象;编译器会认为person(x_p1)==person x_p1,编译器会认为是一个对象的声明
        
        //隐式转换法
        person y_p={10,2};
        person y_p1=y_p;
        //构造函数有多个参数的时候使用{}
    }
    int main()
    {
        test();
      
    }
    
    • 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
    构造函数的使用场景:
    1)用已经创建好的对象为另一个对象赋值
    2)一个对象在函数中作为形参,且该函数被调用
    3)函数中创建的局部对象变量作为返回值为其他对象赋值(编译器不同,可能会优化处理)
    
    • 1
    • 2
    • 3
    • 4
    	#include<iostream>
    using namespace std;
    class person
    {
    public:
        person()
        {
            cout<<"默认构造"<<endl;
        }
        person(int age)
        {
            this->age=age;
            cout<<"赋值构造"<<endl;
        }
        ~person()
        {
            cout<<"析构函数"<<endl;
            cout<<"age="<<age<<endl;
        }
        person(const person &p)
        {
            cout<<"拷贝构造"<<endl;
        }
        int age;
    };
    
    void test_one()
    {
        //使用已经创建完成的对象来初始化另一个对象
        person one_p(20);
        person one_p1(one_p); //person one_p1=person(one_p);person one_p1=one_p;
    }
    
    #define thiree//如果定义了thiree那么就验证 test_thiree
    person test_two
    (
    #ifndef thiree
            person two_p//以值传递的方式给函数参数传值
    #endif
        )
    {
    #ifdef thiree
        person two_p1(20);
        cout<<"two"<<endl;
        return two_p1;
    #endif
    }
    //值返回方式返回局部对象(这里在黑马上说VS使用了拷贝构造,在VScode和Linux虚拟机上使用g++实验出来的结果好像没有使用拷贝构造函数)
    //实际上按道理来说是tes_two()中创建了一个局部的对象two_p1,然后将two_p1赋值给thiree_p;按道理来讲是调用了一次赋值构造,一次拷贝构造,2次析构。这里只看到赋值构造和析构分别为一次,应该是编译的问题
    //编译器好像优化处理了,让我们只看到初始化赋值,和一个析构,中间应该会有拷贝和其他析构。
    person test_thiree()
    {
        person thiree_p=test_two();
        cout<<"thiree"<<endl;
        ++thiree_p.age;
        return thiree_p;
    }
    
    void test_fuor()
    {
        person four_p=test_thiree();
        cout<<"four"<<endl;
    }
    int main()
    {
       // test_one();
    
    #ifndef thiree
        person p;
        test_two(p);
    #endif
    
    //test_thiree();
        test_fuor();
    }
    
    • 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

    C++会提供一个默认的:构造函数,拷贝构造函数(值拷贝,拷贝所有属性),析构函数
    1)如果我们定义了构造函数,它就不会提供默认的构造函数了,其他的仍然提供。
    2)如果我们定义了拷贝构造函数,他就不会提供默认的拷贝构造函数了,其他的仍然提供。

  • 相关阅读:
    同城信息服务源码 本地生活服务小程序源码
    React几种避免子组件无效刷新的方案
    解放双手:VMLogin自动化工具的高效便捷
    2023.10.10 关于 线程安全 问题
    北大肖臻老师《区块链技术与应用》系列课程学习笔记[2]比特币的共识协议
    个人博客文章目录索引(持续更新中...)
    华为OD技术面试-连接后等于目标字符串的字符串对串-2024手撕代码真题
    微机原理与技术接口 实验五 基本IO操作温度控制实验
    负载均衡加权轮询算法
    Python高级进阶(2)----Python装饰器的艺术
  • 原文地址:https://blog.csdn.net/hpx12345678/article/details/125546474