• 【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用 )






    一、构造函数分类




    1、构造函数分类简介


    C++ 构造函数可以分为以下几类 :

    • 无参构造函数 : 最简单也是默认的构造函数 , 函数没有参数 , 如果创建一个对象 , 没有传入参数 , 调用的就是该类型的 构造函数 ;
    • 有参构造函数 : 带参数的 构造函数 , 创建 实例对象 时 , 为成员变量提供初始值 ;
    • 拷贝构造函数 : 拷贝现有 实例对象 , 并以此拷贝的副本为数据 创建一个新的 实例对象 , 相当于创建了一个现有实例对象的副本 , 参数中包含 一个 相同类型 实例对象 引用 ;

    2、构造函数分类代码分析


    定义成员变量 : 下面的简介示例中是以该成员变量为基础进行赋值的 ;

    public:
    	int m_age;
    	char* m_name;
    
    • 1
    • 2
    • 3

    无参构造函数


    无参构造函数 : 只负责为指针类型的成员变量分配内存 , 并赋值一个初始值 , 没有具体的赋值信息 , 该初始化只能为 成员变量 赋值一个默认值 ;

    // 无参构造函数
    Student()
    {
    	// 为 m_name 成员分配内存
    	m_name = (char*)malloc(100);
    
    	// 为 m_name 成员设置字符串值
    	if(m_name != NULL)
    	{
    		strcpy_s(m_name, 5, "name");
    	}
    	
    	// 为 m_age 成员设置初始值
    	m_age = 0;
    
    	cout << "调用无参构造函数" << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    下面的代码 , 是自动调用无参构造函数 , 创建 实例对象 的方法 ;

    	// 调用无参构造函数
    	Student s1;
    	// 打印 Student s1 实例对象值
    	cout << "name : " << s1.m_name << " , age : " << s1.m_age << endl;
    
    • 1
    • 2
    • 3
    • 4

    有参构造函数


    有参构造函数 : 可以将 为 成员变量 赋值的数据放在 构造函数 参数中 , 传递进来 , 并在 构造函数 中 , 为 成员变量 赋值具体的值 ;

    此处需要注意的是 , 这里传入的是 C 语言中的字符串 , 也就是 char * 类型的指针 , 传入后拷贝字符串时 , 需要判定字符串的长度 ;

    // 有参构造函数
    Student(int age, const char* name)
    {
    	// 为 m_name 成员分配内存
    	m_name = (char*)malloc(100);
    
    	// 为 m_name 成员设置字符串值
    	if (m_name != NULL)
    	{
    		strcpy_s(m_name, length, name);
    	}
    
    	// 为 m_age 成员设置初始值
    	m_age = age;
    
    	cout << "调用有参构造函数" << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    下面的代码 , 使用了 2 种方法 , 手动调用了 有参构造函数 ;

    // 调用有参构造函数
    Student s2 = Student(18, "Tom");
    // 打印 Student s1 实例对象值
    cout << "name : " << s2.m_name << " , age : " << s2.m_age << endl;
    
    • 1
    • 2
    • 3
    • 4

    有参构造函数有很多调用方法 , 下一篇博客详细分析每种调用方法的作用 ;


    拷贝构造函数


    拷贝构造函数 : 拷贝构造函数 也是 有参构造函数 中的一种 , 传入的是 相同类型的 常量引用 , 该引用指向的内容在函数内不可修改 ;

    在 " 拷贝构造函数 " 中 , 主要读取 现有 实例对象 中每个 成员变量的值 , 将其赋值给 新创建的 实例对象 中的每个成员变量值 ;

    新创建的 实例对象 , 与原来的 实例对象 只是值相同 , 数据地址完全不同 , 没有引用关系 ;

    	// 拷贝构造函数
    	Student(const Student& obj)
    	{
    		// 为 m_name 成员分配内存
    		m_name = (char*)malloc(100);
    
    		// 为 m_name 成员设置字符串值
    		if (m_name != NULL)
    		{
    			strcpy_s(m_name, sizeof(obj.m_name), obj.m_name);
    		}
    
    		// 为 m_age 成员设置初始值
    		m_age = obj.m_age;
    
    		cout << "调用拷贝构造函数" << endl;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17




    二、代码示例 - 三种类型构造函数定义与调用



    在下面的代码中 , 分别在 Student 类中定义了

    • 无参构造函数
    • 有参构造函数
    • 拷贝构造函数

    分别调用了上述三种类型的 构造函数 ;


    完整代码示例 :

    #include "iostream"
    using namespace std;
    
    class Student
    {
    public:
    
    	// 无参构造函数
    	Student()
    	{
    		// 为 m_name 成员分配内存
    		m_name = (char*)malloc(100);
    
    		// 为 m_name 成员设置字符串值
    		if(m_name != NULL)
    		{
    			strcpy_s(m_name, 5, "name");
    		}
    		
    		// 为 m_age 成员设置初始值
    		m_age = 0;
    
    		cout << "调用无参构造函数" << endl;
    	}
    
    	// 有参构造函数
    	Student(int age, const char* name)
    	{
    		// 为 m_name 成员分配内存
    		m_name = (char*)malloc(100);
    
    		// 为 m_name 成员设置字符串值
    		if (m_name != NULL)
    		{
    			strcpy_s(m_name, sizeof(name), name);
    		}
    
    		// 为 m_age 成员设置初始值
    		m_age = age;
    
    		cout << "调用有参构造函数" << endl;
    	}
    
    	// 拷贝构造函数
    	Student(const Student& obj)
    	{
    		// 为 m_name 成员分配内存
    		m_name = (char*)malloc(100);
    
    		// 为 m_name 成员设置字符串值
    		if (m_name != NULL)
    		{
    			strcpy_s(m_name, sizeof(obj.m_name), obj.m_name);
    		}
    
    		// 为 m_age 成员设置初始值
    		m_age = obj.m_age;
    
    		cout << "调用拷贝构造函数" << endl;
    	}
    
    	~Student()
    	{
    		// 销毁 name 指向的堆内存空间
    		if (m_name != NULL)
    		{
    			free(m_name);
    		}
    		cout << "调用析构函数" << endl;
    	}
    
    public:
    	int m_age;
    	char* m_name;
    };
    
    int main()
    {
    	// 声明 Student 类型实例对象
    	// 调用无参构造函数
    	Student s1;
    	// 打印 Student s1 实例对象值
    	cout << "name : " << s1.m_name << " , age : " << s1.m_age << endl;
    
    	// 手动调用有参构造函数
    	// 直接调用构造函数会产生匿名对象, 涉及到该匿名对象的生命周期
    	Student s2 = Student(18, "Tom");
    	// 打印 Student s1 实例对象值
    	cout << "name : " << s2.m_name << " , age : " << s2.m_age << endl;
    
    	// 调用拷贝构造函数
    	Student s3 = Student(s2);
    	// 打印 Student s3 实例对象值
    	cout << "name : " << s3.m_name << " , age : " << s3.m_age << endl;
    
    	
    
    	// 控制台暂停 , 按任意键继续向后执行
    	system("pause");
        return 0;
    }
    
    • 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
    • 101

    执行结果 :

    调用无参构造函数
    name : name , age : 0
    调用有参构造函数
    name : Tom , age : 18
    调用拷贝构造函数
    name : Tom , age : 18
    Press any key to continue . . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

  • 相关阅读:
    Redis
    Stable Diffusion专场公开课
    STM32_3(GPIO)
    操作系统 | 计算机系统概述
    在线虚拟机安装-云原生边缘计算KubeEdge安装配置(使用负载均衡器LoadBalancer)
    【数字信号处理】序列傅里叶变换(FT)的物理意义
    艾美捷彗星检测试剂盒(单细胞凝胶电泳)化验原理及研究
    [管理与领导-111]:IT人看清职场中的隐性规则 - 8 - 顺势而为在职场中的应用
    【开源】JAVA+Vue.js实现食品生产管理系统
    Mysql数据库索引
  • 原文地址:https://blog.csdn.net/han1202012/article/details/132811370