• 【C++】构造函数初始化列表 ① ( 类对象作为成员变量时的构造函数问题 | 构造函数初始化列表语法规则 )






    一、类对象作为成员变量时的构造函数问题




    1、问题描述


    如果 一个类 A 的对象 作为 另外一个类 B 的成员变量时 ,

    在以下场景会报错 :

    • 为类 A 定义 有参的 构造函数 , 那么 A 的无参默认构造函数就失效了 ;
    • 此时使用 默认无参构造函数 初始化 B , 就会报错 ;

    在一个类中 , 其成员变量是 带有参构造函数 的类型 , 这种情况下没有调用 有参构造函数的机会 , 此时就会出现 编译报错情况 ;


    在下面的代码中 , A 只有通过 有参构造函数 A(int age, int height) 进行初始化 , 无法再使用 无参构造函数 ;

    class A
    {
    public:
    	// 带参构造函数
    	A(int age, int height)
    	{
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在 B 中 , 如下声明 A 成员变量 , 只能调用 A 的 无参构造函数创建 A 对象 , 但是 A 的 无参构造函数无法使用 , 必须使用 A 的有参构造函数 , 这里就出现问题 , 报错 “B::B(void)”: 由于 数据成员“B::m_a”不具备相应的 默认构造函数 或重载解决不明确,因此已隐式删除函数 ;

    class B
    {
    public:
    	int m_age;		// 年龄
    	A m_a;			// A 类型成员变量
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    解决上述问题的方案 就是 C++ 中的 构造函数 初始化列表 ;


    2、错误代码示例


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class A
    {
    public:
    	// 带参构造函数
    	A(int age, int height)
    	{
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    class B
    {
    public:
    	int m_age;		// 年龄
    	A m_a;			// A 类型成员变量
    };
    
    
    int main()
    {
    	// 通过 B 的默认无参构造函数初始化 B 对象
    	B b;
    
    
    	// 控制台暂停 , 按任意键继续向后执行
    	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

    执行结果 :

    已启动生成…
    1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
    1>hello_world.cpp
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(28): error C2280:B::B(void): 尝试引用已删除的函数
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(22): message : 编译器已在此处生成“B::B”
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(22,1): message :B::B(void): 由于 数据成员“B::m_a”不具备相应的 默认构造函数 或重载解决不明确,因此已隐式删除函数
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(21): message : 参见“B::m_a”的声明
    1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
    ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述





    二、构造函数初始化列表




    1、构造函数初始化列表语法规则


    在 C++ 语言中 , 构造函数初始化列表 是一种用于初始化类的成员变量的方法 ;


    构造函数初始化列表 可实现功能 :

    • 为成员变量提供初始值
    • 调用其他 成员变量的 构造函数 来初始化成员变量

    构造函数初始化列表语法规则 :

    构造函数() : 成员变量名称(成员变量值) , 成员变量名称(成员变量值) 
    {
    	// 构造函数内容
    }
    
    • 1
    • 2
    • 3
    • 4
    • 构造函数初始化列表 位置在 构造函数 的 参数列表之后 , 冒号 : 与花括号 {} 之间 ;
    • 使用 逗号 , 分隔 ;
    • 初始化列表中的元素由 成员变量的名称 和 初始值组成 , 使用等号 = 连接 ;

    在下面的代码中 , 为 B 类定义了默认的构造函数 , 其中定义了 构造函数 初始化列表 ;

    在 初始化列表中 ,

    • m_age(10) 是 为 m_age 提供了初始值 ;
    • m_a(10, 150) 是 调用了 A 的有参构造函数 ;

    代码示例 :

    class B
    {
    public:
    	B() : m_age(10) , m_a(10, 150)
    	{}
    public:
    	int m_age;		// 年龄
    	A m_a;			// A 类型成员变量
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、代码示例 - 构造函数初始化列表语法规则


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class A
    {
    public:
    	// 带参构造函数
    	A(int age, int height)
    	{
    		m_age = age;
    		m_height = height;
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    class B
    {
    public:
    	B() : m_age(10) , m_a(10, 150)
    	{}
    public:
    	int m_age;		// 年龄
    	A m_a;			// A 类型成员变量
    };
    
    
    int main()
    {
    	// 通过 B 的默认无参构造函数初始化 B 对象
    	B b;
    
    
    	// 控制台暂停 , 按任意键继续向后执行
    	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

    执行结果 :

    在这里插入图片描述

  • 相关阅读:
    【vue循环】如何显示商家与商家里的商品数据?
    测试的流程已经测完,仍然会导致一些 BUG 流入到线上,如何规避和解决?
    Linux--进程--进程-父进程退出
    速度轴模拟量控制FB(博途SCL+三菱ST代码)
    自媒体新手入门攻略,学习干货内容了解运营技巧
    CNN 网络结构简介
    R语言ggplot2可视化:使用ggpubr包的ggviolin函数可视化小提琴图、设置palette参数自定义不同水平小提琴图的边框颜色
    实际电容的频率特性
    03_如何仅用递归函数和栈操作逆序一个栈
    Spark-Transformation以及Action开发实战
  • 原文地址:https://blog.csdn.net/han1202012/article/details/132962695