【C++】构造函数初始化列表 ③ ( 构造函数 的 初始化列表 中 为 const 成员变量初始化 )

2023-09-19 11:13:28


构造函数初始化列表 总结 :

  • 初始化列表 可以 为 类的 成员变量 提供初始值 ;
  • 初始化列表 可以 调用 类的 成员变量 类型的 构造函数 进行成员变量初始化操作 ;
  • 初始化列表 可以 使用 构造函数 中传入的 参数 ;
  • 类初始化时 , 根据定义顺序 , 先调用 成员变量的 构造函数 , 然后调用外部类构造函数 , 析构函数正好相反 ;
  • 实例对象 的 const 成员变量 必须只能在 初始化列表 中进行 初始化 , 所有的构造函数都要进行初始化操作 ;




一、构造函数 的 初始化列表 中 为 const 成员变量初始化




1、初始化 const 常量成员


如果 类 中定义了 被 const 修饰 的 成员变量 , 那么该成员变量 必须被初始化 , 否则会报错 ;

对象中的 const 成员 必须在 声明后 立刻进行初始化 ;

const 成员的初始化 只能通过 构造函数 的 初始化列表 进行初始化 ;

注意 : 这里区分 初始化 与 赋值 ,

  • 初始化 是 变量 声明时 同时 为其 设置一个 初始化值 ;
  • 赋值 是 变量 声明以后 , 再对变量进行赋值 ;

const 成员变量 是常量 , 是 无法在声明后 进行赋值 的 , 因此 这里 必须在 构造函数的 初始化列表中 对 const 成员变量 进行赋值 ;


2、错误代码示例 - 没有初始化常量成员


在下面的 类 B 中 , 定义了常量 const int m_const_int;

没有对该常量 进行初始化 操作 , 在编译运行时 , 就会报错 ;

class B
{
public:
	B() : m_age(10), m_a(10, 150)
	{}

	// 构造函数中的参数可以作为 参数列表 中的参数值
	B(int age, int ageOfA, int heightOfA) : m_age(age), m_a(ageOfA, heightOfA)
	{
		cout << "执行 B 的构造函数" << endl;
	}

	~B()
	{
		cout << "执行 B 的析构函数" << endl;
	}
public:
	int m_age;		// 年龄
	A m_a;			// A 类型成员变量
	const int m_const_int;	// 常量成员
};

执行结果 :

已启动生成…
1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>hello_world.cpp
1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(29,2): error C2789: “B::m_const_int”: 必须初始化常量限定类型的对象
1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(44): message : 参见“B::m_const_int”的声明
1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(33,2): error C2789: “B::m_const_int”: 必须初始化常量限定类型的对象
1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(44): message : 参见“B::m_const_int”的声明
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========

在编译时 , 所有的 构造函数 上 , 都会报错 ;

所有的 构造函数 中 , 都必须 在 初始化列表中 , 对 常量成员 进行初始化操作 ;

在这里插入图片描述


3、正确代码示例 - 在初始化列表中初始化常量成员


在下面的 类 B 中 , 所有的 构造函数 中 , 都要使用 初始化列表 初始化 常量成员 , 只要遗漏一个构造函数 没有对 常量成员 进行初始化 , 就会报错 ;


代码示例 :

class B
{
public:
	B() : m_age(10), m_a(10, 150), m_const_int(888)
	{}

	// 构造函数中的参数可以作为 参数列表 中的参数值
	B(int age, int ageOfA, int heightOfA) : m_age(age), m_a(ageOfA, heightOfA), m_const_int(888)
	{
		cout << "执行 B 的构造函数" << endl;
	}

	~B()
	{
		cout << "执行 B 的析构函数" << endl;
	}
public:
	int m_age;		// 年龄
	A m_a;			// A 类型成员变量
	const int m_const_int;	// 常量成员
};

执行结果 :

在这里插入图片描述


4、完整代码示例


完整代码示例 :

#include "iostream"
using namespace std;

class A
{
public:
	// 带参构造函数
	A(int age, int height)
	{
		m_age = age;
		m_height = height;
		cout << "执行 A 的构造函数" << endl;
	}

	~A()
	{
		cout << "执行 A 的析构函数" << endl;
	}

public:
	int m_age;		// 年龄
	int m_height;	// 身高
};

class B
{
public:
	B() : m_age(10), m_a(10, 150), m_const_int(888)
	{}

	// 构造函数中的参数可以作为 参数列表 中的参数值
	B(int age, int ageOfA, int heightOfA) : m_age(age), m_a(ageOfA, heightOfA), m_const_int(888)
	{
		cout << "执行 B 的构造函数" << endl;
	}

	~B()
	{
		cout << "执行 B 的析构函数" << endl;
	}
public:
	int m_age;		// 年龄
	A m_a;			// A 类型成员变量
	const int m_const_int;	// 常量成员
};


int main()
{
	// 通过 B 的有参构造函数
	// 其中 构造函数中的参数 作为 参数列表 中的参数值
	B b(10, 10, 150);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
}

执行结果 :

执行 A 的构造函数
执行 B 的构造函数
Press any key to continue . . .
执行 B 的析构函数
执行 A 的析构函数

D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\Debug\HelloWorld.exe (进程 20756)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

在这里插入图片描述

更多推荐

mianshiyan资料汇总(整理后)

前端优化方式css3html5Turbopackes6的新特性BigInt微前端cdnWebComponent作用域和执行上下文JS的堆栈内存分配js垃圾回收机制,v8的垃圾回收机制,v8引擎为啥快前端路由hash和history的区别前端攻击反爬虫加密跨域cookiesessionjwt相关Js闭包实际的用途原型链防

探究Nginx应用场景

1静态资源Nginx是一个流行的Web服务器和反向代理服务器,它可以用于托管静态资源。下面是一个简单的案例,展示了如何使用Nginx来提供静态资源。假设你有一个名为example.com的域名,并且你希望使用Nginx来托管位于/var/www/html目录下的静态资源。配置静态资源路径:在Nginx中,可以使用roo

springboot中注解介绍

springboot中的bean在Java编程语言中,"Bean"通常指的是JavaBean,它是一种符合特定规范的普通Java类。JavaBean类具有以下特点:封装性:JavaBean使用私有的字段(成员变量)和公共的Getter和Setter方法来封装数据,以实现对属性的访问控制。无参构造函数:JavaBean通

Spring之IOC容器(依赖注入)&基本介绍&基本配置&多模块化

标题一:什么是spring,它能够做什么?Spring是一个开源框架,它由RodJohnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都

SpringMVC之JSON数据返回&异常处理机制

目录前言一、JSON数据返回1.导入依赖2.配置spring-mvc.xml3.使用@ResponseBody注解4.Jackson4.1.介绍4.2.常用注解二、异常处理机制1.为什么要全局异常处理2.异常处理思路3.SpringMVC异常分类4.综合案例4.1.异常处理方式一4.2.异常处理方式二4.3异常处理方式

== 和 equals 的区别

😀前言我们首先介绍了==运算符,它主要用于比较对象的引用地址。我们明确了它适用于基本数据类型和引用类型,以及其默认行为。然后,我们详细讨论了equals方法,它是一个方法,通常用于比较对象的内容。我们强调了需要在自定义类中重写equals方法以便实现对象内容的比较,同时提到了一些重写equals方法时需要遵循的约定�

初创型企业如何申报专精特新中小企业!?

数据显示,我国已培育7万多家技术专精特新中小民营企业,其中自己专精特新“小巨人”企业8997家。去年新上市公司企业中,专精特新中小民营企业占59%。今年我国将深入研究实施提供优质服务企业进行梯度培育工程,力争今年全国专精特新中小企业员工数量超过8万家,计划培育100个左右中小企业文化特色社会产业集群。那么初创型企业申报

【uniapp】Dcloud的uni手机号一键登录,具体实现及踩过的坑,调用uniCloud.getPhoneNumber(),uni.login()等

一键登录Dcloud官网请戳这里,感兴趣的可以看看官网,有很详细的示例,选择App一键登录,可以看到一些常用的概述比如:1、调用uni.login就能弹出一键登录的页面2、一键登录的流程,可以选择先预登录uni.prelogin()或直接登录uni.login()3、要先开通Dcloud一键登录服务,在Dcloud开发

基于5G网络的智能车间MES设计方案

导读在数字化转型建设过程中,机械制造企业的难点是智能车间的设计。随着5G技术的发展,大量的带网络接口的智能设备的投入使用,智能车间的实施成为可能。本文从车间生产计划调度、过程管控、设备管理、质量管理、能耗管理和物流仓储等方面提出了车间MES执行系统设计的要求,同时对企业实施MES的过程提出了四个注意事项。01引言随着网

详解SpringBoot的核心特性

详解SpringBoot的核心特性SpringBoot是一个用于简化Spring应用程序开发的框架,它提供了一系列核心特性,使得开发者能够更快速、更简单地构建和部署Spring应用程序。本文将详细介绍SpringBoot的五个核心特性,并为每个特性提供三个子特性的详细解释。1.独立运行的Spring应用程序Spring

在SpringBoot中如何整合消息服务组件?

在开发中,消息服务组件在系统架构中扮演着举足轻重的角色。本文将介绍消息服务组件的基本概念,以及如何在SpringBoot中整合常见的消息服务组件,如ActiveMQ、RabbitMQ和Kafka。最后,我们将探讨整合消息服务组件在实际应用场景中的优势。1.消息服务组件的基本概念1.1什么是消息服务组件消息服务组件作为一

热文推荐