【C++ | 构造函数】类的构造函数详解

news2024/12/24 0:20:07

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
⏰发布时间⏰:2024-06-06 09:02:26

本文未经允许,不得转发!!!

目录

  • 🎄一、为什么需要构造函数
  • 🎄二、什么是构造函数
  • 🎄三、使用构造函数
  • 🎄四、默认构造函数
  • 🎄五、成员初始化列表
  • 🎄六、总结


在这里插入图片描述

🎄一、为什么需要构造函数

C++的目标之一是让使用类对象就像使用标准类型一样。如果没有构造函数,就无法创建对象并初始化。下面代码演示了CDate类对象初始化时会报错。

int year = 2001// 有效初始化

struct thing
{
	char * pn;
	int m;
};
thing amabob = {"wodget", -23};	// 有效初始化

class CDate
{
	int year;
	int mon;
	int day;
};
CDate date = {2024, 06, 05}; // 编译报错

这里CDate类对象初始化出错的原因是,数据部分是私有的,只能通过类成员函数去访问,如果将数据设置为公有会违背“数据隐藏”的思想。所以,我们需要一个成员函数,能够在创建对象时初始化数据部分。C++提供了这样的函数——构造函数。


在这里插入图片描述

🎄二、什么是构造函数

构造函数:专门用于构造新对象、 将值赋给它们的数据成员。

构造函数的函数名类名相同,没有返回值类型,会在创建对象时自动调用一次,目的是初始化对象。

下面看看怎样声明和定义构造函数?CDate 类为例,代码如下:

class CDate
{
public:
	CDate(int year, int mon, int day); // 构造函数声明
private:
	int m_year;
	int m_mon;
	int m_day;
};

// 构造函数定义
CDate::CDate(int year, int mon, int day)
{
	m_year = year;
	m_mon = mon;
	m_day = day;
}

在编写类成员函数时,需要注意,参数名不能和类成员名相同,否则最终代码会写出year=year,为了避免这种情况,常见的做法是在数据成员前加m_前缀表示其为类成员。


在这里插入图片描述

🎄三、使用构造函数

C++提供了两种使用构造函数来初始化对象的方式。

  • 1、显式地调用构造函数:
    CDate date = CDate(2024,6,5);
    
  • 2、隐式地调用构造函数:
    CDate date(2024,6,5);	// 这种形式更紧凑
    

每次创建类对象(甚至使用 new 动态分配内存)时,C++都自动调用类构造函数。下面是将构造函数与 new 一起使用的方法,这种情况下,对象没有名称,但可以使用指针来管理该对象:

CDate *pDate = new CDate(2024,6,5);

另外,如果编译器支持C++11,则支持下面三种写法:

CDate date = {2024,6,5};	// C++11
CDate date{2024,6,5};
CDate *pDate = new CDate{2024,6,5};

注意:无法使用对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的。因此构造函数被用来创建对象,而不能通过对象来调用。

结合上个小节,下面代码演示了怎么声明、定义、使用构造函数:

// g++ 09_Construct_Date.cpp
#include <iostream>

using namespace std;

class CDate
{
public:
	CDate(int year, int mon, int day); // 构造函数声明

	void show()
	{
		cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;
	}

private:
	int m_year;
	int m_mon;
	int m_day;
};

// 构造函数定义
CDate::CDate(int year, int mon, int day)
{
	m_year = year;
	m_mon = mon;
	m_day = day;
}

int main()
{
	CDate date = CDate(2024,6,5);
	date.show();
	
	CDate date1(2024,6,6);
	date1.show();
	
	CDate *pDate = new CDate(2024,6,7);
	pDate->show();
	
	return 0;
}

运行结果:
在这里插入图片描述


在这里插入图片描述

🎄四、默认构造函数

首先要清楚一点,构造函数可以存在多个,并且形成重载的关系,编译器会根据参数自动选择调用那个构造函数。我们可以改一下上面代码的类如下,多了两个重载的构造函数:

class CDate
{
public:
	CDate(int year, int mon, int day);	// 构造函数声明
	CDate(int year, int mon);			// 构造函数声明
	CDate();							// 构造函数声明

	void show()
	{
		cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;
	}

private:
	int m_year;
	int m_mon;
	int m_day;
};

默认构造函数:如果类没有提供任何的构造函数,则编译器会自动提供一个默认构造函数,它没有参数,也不做任何工作。
CDate 类的默认构造函数可能如下:

CDate::CDate(){
}

在未提供显式初始值去创建对象时会调用默认构造函数,如下:

CDate date;	// 未显示提供初始值,会调用默认构造函数

注意:如果类提供了构造函数,则编译器就不会在提供默认构造函数。如果该类需要使用默认构造函数,则需要程序员在类中为其提供默认构造函数,或者将其中一个构造函数的参数都给默认值。

在设计类时, 通常应提供对所有类成员做隐式初始化的默认构造函数。

上个小节代码中,我们为 CDate 类只提供了一个带有构造函数,所以,如果程序中使用 CDate date; 则会报错:error: no matching function for call to ‘CDate::CDate()’,下面我们修改一下,为其提供一个默认构造函数:

// g++ 09_Construct_Date.cpp
#include <iostream>

using namespace std;

class CDate
{
public:
	CDate(int year, int mon, int day);	// 构造函数声明
	CDate(){}							// 默认构造函数

	void show()
	{
		cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;
	}

private:
	int m_year;
	int m_mon;
	int m_day;
};

// 构造函数定义
CDate::CDate(int year, int mon, int day)
{
	m_year = year;
	m_mon = mon;
	m_day = day;
}

int main()
{
	CDate date = CDate(2024,6,5);
	date.show();
	
	CDate date1(2024,6,6);
	date1.show();
	
	CDate *pDate = new CDate(2024,6,7);
	pDate->show();
	
	CDate date_default;
	date_default.show();
	
	return 0;
}

运行结果如下:date_default 对象的值是乱码,因为我们的提供的默认构造没做任何东西,正常编写代码时会做一些初始化动作。
在这里插入图片描述


在这里插入图片描述

🎄五、成员初始化列表

在C++中,const修饰的变量必须初始化,引用也必须初始化。如果一个类存在const成员或引用成员,则上面的构造函数无法对这两类成员进行初始化。C++为构造函数提供了 成员初始化列表 来解决这类问题。

成员初始化列表:成员初始化列表由逗号分隔的初始化列表组成(前面带冒号)。它位于构造函数参数列表的右括号之后、函数体左括号之前。

CDate 类的 成员初始化列表 可以写成下面代码:

CDate():m_year(2024), m_mon(1), m_day(1)
{}

注意成员初始化列表 只能在构造函数中使用。一旦类中出现const成员引用成员,则编译器会要求每个构造函数都去初始化这两类成员,且必须使用 成员初始化列表

下面对上个小节的代码修改一下,在 CDate 类中声明一个 const 变量,代码如下:

// g++ 09_Construct_Date.cpp
#include <iostream>

using namespace std;

class CDate
{
public:
	CDate(int year, int mon, int day);	// 构造函数声明
	//CDate(){}							// 默认构造函数
	CDate():Month(12)					// 默认构造函数
	{
		//Month = 12;		// 报错:assignment of read-only member ‘CDate::Month’
		m_year = 2024;
		m_mon = 1;
		m_day = 1;
	}

	void show()
	{
		cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;
	}

private:
	int m_year;
	int m_mon;
	int m_day;
	const int Month;
};

// 构造函数定义
CDate::CDate(int year, int mon, int day):Month(12)
{
	m_year = year;
	m_mon = mon;
	m_day = day;
}

int main()
{
	CDate date = CDate(2024,6,5);
	date.show();
	
	CDate date1(2024,6,6);
	date1.show();
	
	CDate *pDate = new CDate(2024,6,7);
	pDate->show();
	
	CDate date_default;
	date_default.show();
	
	return 0;
}

在这里插入图片描述

🎄六、总结

👉本文详细介绍了C++中的构造函数,怎样声明、定义、使用构造函数,默认构造函数,构造函数的成员初始化列表。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考:
《C++ Primer Plus》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1792786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为设备配置静态路由和默认路由

华为设备配置静态路由和默认路由 理论部分知识&#xff1a; 路由分为两个大类&#xff1a;静态路由-----动态路由 静态路由&#xff1a;手工指定&#xff0c;适用于小规模的网络应用场景&#xff0c;如果网络规模变大&#xff0c;这样的方式非常不适合而且容易出错。 语法&…

【软件测试】6.设计测试用例的设计方法

目录 1.基于需求的设计方法 2.具体的设计方法 2.1等价类 2.2边界值 2.3正交法 2.4判定表法 2.5场景法 2.6 错误猜测法 1.基于需求的设计方法 基于需求的设计方法也是总的设计测试用例的方法&#xff0c;在工作中&#xff0c;我们需要参考需求文档/产品规格说明书来设计…

【AI大模型】Function Calling

目录 什么是Function Calling 示例 1&#xff1a;调用本地函数 Function Calling 的注意事项 支持 Function Calling 的国产大模型 百度文心大模型 MiniMax ChatGLM3-6B 讯飞星火 3.0 通义千问 几条经验总结 什么是Function Calling Function Calling 是一种函数调用机…

【游戏】Goc赚钱模拟器1.0版

Hello!大家好&#xff0c;我是学霸小羊&#xff0c;今天分享一个Goc游戏。 //注&#xff1a;以下代码为Goc原创代码。 大家可以在下面网址写入代码www.51goc.com慧通教育http://www.51goc.com注&#xff1a;Goc编辑器路径&#xff1a; www.51goc.com ➡ 登录 ➡ 游客登陆 ➡…

【OpenHarmony】ArkTS 语法基础 ⑤ ( ArkTS 状态管理 | @State 装饰器定义状态数据 | 使用状态数据渲染组件 )

文章目录 一、ArkTS 状态管理 - State 装饰器1、State 装饰器定义状态数据2、State 装饰器定义状态数据 - 示例分析3、使用 State 装饰器定义的状态数据渲染组件 - 示例分析 二、完整代码示例1、完整自定义组件代码示例2、展示效果 参考文档 : <HarmonyOS第一课>ArkTS开发…

实验七、创建小型实验拓扑《计算机网络》

早检到底是谁发明出来的。 一、实验目的 完成本实验后&#xff0c;您将能够&#xff1a; • 设计逻辑网络。 • 配置物理实验拓扑。 • 配置 LAN 逻辑拓扑。 • 验证 LAN 连通性。 二、实验任务 在本实验中&#xff0c;将要求您连接网络设备并配置主机实现基本的网络…

【Python】 深入理解Pandas中的iloc和loc:数据选择的艺术

基本原理 在Python的Pandas库中&#xff0c;数据选择是数据分析和处理的基础。iloc和loc是两种常用的数据选择方法&#xff0c;它们都允许用户根据索引位置或标签来选择数据。然而&#xff0c;它们在行为和用途上存在一些关键的差异。 iloc iloc是基于整数索引的&#xff0c…

微信小程序多端框架打包后发布到华为市场

app上架华为应用市场 一、android 发布到华为应用市场 1、华为应用市场注册开发者账号 https://developer.huawei.com/consumer/cn/?ha_sourcesem&ha_sourceId89000605 2、进行企业认证 3、app隐私弹窗 miniapp-privacy.json 1、协议弹窗内容&#xff1a; {"tit…

基于python的网上挂号预约系统-计算机毕业设计源码89352

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;医院当然也不例外。网上挂号预约系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;采用Py…

华为坤灵管理型交换机S300,S500,S310,S210,S220,S200 web端开局配置

一. 准备线缆 1.笔记本或没有COM口的电脑,需准备转接线,并安装好随线光盘的驱动,检查设备管理器中COM口是否正常 【GKREN】console调试线适用于华为h3c思科交换机usb转RJ45/RS232 2.连接电脑与交换机的CONSOLE口 二.准备软件putty。 Download PuTTY: latest release (0.81) …

Linux中Apache网站基于Http服务的访问限制(基于地址/用户)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f468;‍&#x1f4bb;Linux高级管理专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月3日11点44分 &#x1f004;️文章质量&#xff1a;95分 为了更好地控制对网站资源的访问&#xff0c;可…

cmake使用(01)

顶层CMakeLists.txt cmake_minimum_required (VERSION 3.5)# 配置 交叉编译 放置在 project() 命令之前# /opt/fslc-wayland/2.5.2/sysroots/aarch64-fslc-linux/usr/bin/make: error # while loading shared libraries: libdl.so.2: cannot open shared object file: # No su…

spring boot3登录开发-2(3邮件验证码接口实现)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 目录 写在前面 上文衔接 接口设计与实现 1.接口分析 2.实现思路 3.代码实现 1.定义验证码短信HTML模板枚举类 2.定义验证码业务接口 3. 验证码业务接口实现 4.控制层代码 4.测试 写…

用 Axios 封装一个双 token 无感刷新

为什么要用双Token无感刷新&#xff0c;它解决了什么问题&#xff1f; 为了保证安全性&#xff0c;后端设置的Token不可能长期有效&#xff0c;过了一段时间Token就会失效。而发送网络请求的过程又是需要携带Token的&#xff0c;一旦Token失效&#xff0c;用户就要重新登陆&…

Nginx 功能简介及代理配置

一、Nginx功能简介 Nginx是一款开源的高性能HTTP和反向代理服务器&#xff0c;具有轻量级的设计、高并发能力、内存占用低以及配置简单等特点&#xff0c;并且支持热部署。以下是Nginx的主要功能&#xff1a; 静态内容服务&#xff1a;Nginx可以作为一个高性能的静态文件服务…

笔记 | 软件工程01:从程序到软件

1 软件工程知识域 2 程序 2.1 何为程序及程序的质量要求 何为程序&#xff1a; 理解&#xff1a;软件工程可能就是在弥补OOP语言与自然语言之间还存在的鸿沟 2.1.1 程序质量的内在和外在体现 2.1.2 程序质量的语法和语义体现 2.2 编写代码的基本原则 2.3 程序质量保证方法 …

软件三班20240605

文章目录 1.创建工程和模块2.添加 web支持3.创建前端代码4.添加servlet 依赖5. 代码6.案例2 1.创建工程和模块 2.添加 web支持 方法1 方法2 3.创建前端代码 4.添加servlet 依赖 5. 代码 <!DOCTYPE html> <html lang"en"> <head><meta c…

xml创建模型组合体

XML创建模型组合体 创建步骤模型准备模型处理模型文件XML编写 效果 创建步骤 模型准备 CAD 提供的原始模型如下&#xff1a; 该模型存在的问题&#xff1a; 单位问题&#xff1a;CAD出图的是 mm 为单位&#xff0c;但是 mujoco 建模这边用的是以 m 为单位的&#xff1b;原点…

arcpy批量导出图且图名为shp属性值

1.打开arcmap加载需要导出的图。需求是逐村显示“村界内图斑”并导出为图&#xff0c;在导出每个村时不显示周围的村和“村界内图斑” 2.arcmap上方空白处右键打开“数据驱动页面” 3.在“数据驱动页面”工具条点击第一个图标&#xff0c;打开“设置数据驱动页面” 4.在“设置…