文章目录
- 一、类对象作为成员变量时的构造函数问题
- 1、问题描述
- 2、错误代码示例
- 二、构造函数初始化列表
- 1、构造函数初始化列表语法规则
- 2、代码示例 - 构造函数初始化列表语法规则
一、类对象作为成员变量时的构造函数问题
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; // 身高
};
在 B 中 , 如下声明 A 成员变量 , 只能调用 A 的 无参构造函数创建 A 对象 , 但是 A 的 无参构造函数无法使用 , 必须使用 A 的有参构造函数 , 这里就出现问题 , 报错 “B::B(void)”: 由于 数据成员“B::m_a”不具备相应的 默认构造函数 或重载解决不明确,因此已隐式删除函数
;
class B
{
public:
int m_age; // 年龄
A m_a; // A 类型成员变量
};
解决上述问题的方案 就是 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>------ 已启动生成: 项目: 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、构造函数初始化列表语法规则
在 C++ 语言中 , 构造函数初始化列表 是一种用于初始化类的成员变量的方法 ;
构造函数初始化列表 可实现功能 :
- 为成员变量提供初始值
- 调用其他 成员变量的 构造函数 来初始化成员变量
构造函数初始化列表语法规则 :
构造函数() : 成员变量名称(成员变量值) , 成员变量名称(成员变量值)
{
// 构造函数内容
}
- 构造函数初始化列表 位置在 构造函数 的 参数列表之后 , 冒号
:
与花括号{}
之间 ; - 使用 逗号
,
分隔 ; - 初始化列表中的元素由 成员变量的名称 和 初始值组成 , 使用等号
=
连接 ;
在下面的代码中 , 为 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 类型成员变量
};
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;
}
执行结果 :