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

2023-09-18 22:15:00





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




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;
}

执行结果 :

在这里插入图片描述

更多推荐

基于Java+vue前后端分离安全教育平台设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

卷运维不如卷网络安全

最近发现很多从事运维的选择了辞职,重新规划自己的职业发展方向。运维工程师这个岗位在IT行业里面确实是处于最底层的,不管什么环节出现问题,基本都是运维背锅。背锅也就罢了,薪资水平也比不上别的岗位。一般运维的薪资水平大多数都是6-9K,还要高频出差。规模小一点的公司省内出差,规模稍微大一点的公司基本全国各地到处飞,而且一呆

《人件》读书笔记

作者与书籍简介:《人件》1987年第一次出版,这本书与《人月神话》共同被誉为软件管理图书的“双子星”。作者TomDeMarco与TimothyLister均为美国咨询师。《人件》是两位作者在越洋航班中的思想碰撞中产生的,“软件系统的主要问题不在技术,而在于社会性因素”这一想法一经产生,作者就展开了一系列的案例研究,一步

QT chart图表(温度曲线实战)

文章目录前言一、QChart介绍二、帮助文档三、QGraphicsView四、QChart的显示总结前言本篇文章开始将带大家学习QTchart图表,后面我们将完成一个小项目,动态温度曲线,并且将本项目移植到ARM开发板上使用DHT11实时检测温度湿度。一、QChart介绍QT的QChart是一个用于绘制各种类型图表的Q

备战2024秋招面试题-负载均衡常见的算法

前言:\textcolor{Green}{前言:}前言:💞快秋招了,那么这个专栏就专门来记录一下,同时呢整理一下常见面试题💞部分题目来自自己的面试题,部分题目来自网络整理给我冲学习目标:面试题:算法题:完成?学习目标:负载均衡常见的算法算法题:组合总和面试题:负载均衡常见的算法负载均衡指的是将用户请求分摊到不同的服

设计模式:迭代器模式

目录组件代码示例源码中使用优劣点总结迭代器模式(IteratorPattern)是一种行为型设计模式,它提供了一种访问聚合对象中各个元素的方法,而无需暴露聚合对象的内部表示。迭代器模式将遍历和操作聚合对象的责任分离,使得遍历算法可以独立于聚合对象变化而变化。在迭代器模式中,聚合对象包含一个迭代器接口,定义了访问和遍历元

python从入门到精通(一)

自己也有三四年的码龄了,目前,重拾起自己的博客,记录自己的学习笔记,为大家提供优质内容,也来巩固自己的学习内容。很开心也成功成为了一名研究生,张张的研究方向是图像处理和计算机视觉这一块,有这方面的小伙伴可以一起探讨学习。接下来先把python学扎实,gogogo!!!以下内容来自于黑马程序员的视频,作者只是做了一下视频

Github上1.1KFork的C++笔记

编程语言(C/C++)原文链接,如果觉得本文对你有所帮助,欢迎去原地址点个Star⭐。侵删https://github.com/linw7/Skill-Tre目录Chapter1Chapter2Chapter3Chapter4编程基础面向对象基础标准模板库编译及调试内容Chapter1:编程基础C/C++的内容又多又杂

结构型设计模式

结构型设计模式结构型设计模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。结构模式包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、亨元模式。1.代理模式实现方式:代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是为了控制访问,而非加强功能

HTML实现移动端布局与页面自适应

我们所说的布局方式,这里我们通常指的是width和height在不同页面情况下面的改变。常见页面的布局方式有静态布局(px布局,就是固定其高宽,不论页面怎样放大缩小,其占领的依旧是,使用px固定了的高宽)流式布局(LiquidLayout)主要的划分区域的尺寸使用百分数(100%)(搭配min-*、max-*属性使用)

【Intel 黑客松大赛】基于YOLO的杂草-农作物检测分类系统

目录一、赛题简介:计算机视觉挑战——检测并清除杂草二、基于YOLO的杂草-农作物检测分类2.1、YOLO简介2.2、基于YOLO的杂草-农作物检测分类解决方案三、基于YOLO的杂草-农作物检测分类系统设计3.1、基于flask框架的demo应用程序后端3.2、基于Vue框架的demo应用程序前端四、InteloneAP

热文推荐