【C++】构造函数详解

news2024/11/16 11:28:48

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 前言:
  • 一、 什么是构造函数
  • 二、构造函数的特征特征
  • 三、构造函数类型
    • 1.无参构造
    • 2.带参构造函数
    • 3.全缺省构造函数(后面有补充)
      • (1)传入前一个,前两个,全传入。
      • (2)传入0个参数时
  • 四、默认构造函数意义:
    • 1.问题引入:
    • 2.内置类型和自定义类型
  • 五、补充
  • 后续补充!

前言:

使用类实例化对象时,每一个对象都要进行初始化,都要进行调用初始化函数,这个操作是实例化对象的必要操作,那么有没有更好的方式来简化这个调用操作。于是C++便推出了构造函数

一、 什么是构造函数

构造函数是特殊的成员函数,构造函数千万不要认为它是用来创建对象的,其实构造函数的主要任务并不是开空间创建对象,而是初始化对象。

  • 没有构造函数,需要自己手动写初始化函数,如下:
class Data
{
public:
	void Init(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print(){}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	d1.Init(1999, 1, 1);
	d1.print();
	Data d2;
	d2.Init(2023, 1, 1);
	d2.print();
	return 0;
}
  • 使用构造函数
class DData
{
public:
	DData(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print() 
	{
		cout << "时间:" << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	DData d1(2023, 11, 14);
	d1.print();
	return 0;
}

二、构造函数的特征特征

  1. 函数名类名相同。
  2. 返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载
    在这里插入图片描述
    如上代码,两个Data构造函数,构成重载,但是不能同时存在,无参调用时会造成歧义(不知道调哪一个)。所以,在写构造函数时使用全缺省方式,更加合适。

三、构造函数类型

1.无参构造

格式:Data d1

class Data
{
public:
//这里不写构造函数

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	return 0;
}

2.带参构造函数

格式 Data d1(2023, 11, 14);对应构造函数中的三个参数

class DData
{
public:
//构造函数
	Data(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print() 
	{
		cout << "时间:" << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023, 11, 14);
	d1.print();
	return 0;
}

3.全缺省构造函数(后面有补充)

使用全缺省构造函数,它的特殊之处在于带有初始值。如果传参时没有覆盖,那么就会将自带的初始值赋给变量。

(1)传入前一个,前两个,全传入。

如下代码,我们只传入前两个参数或者只传入前一个参数又或是全传入。

Data d1(19996); 或者 Data d1(1999);或者Data d1(199966)
class DData
{
public:
//构造函数
	Data(int year=1, int month=1, int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print() 
	{
		cout << "时间:" << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(19996);
	d1.print();
	return 0;
}

在这里插入图片描述

(2)传入0个参数时

当传入0个参数时,应该怎么写,会不会和无参构造冲突?

其实当传入0个参数时,我们应该写成Data d1;而不能写成Data d1();的形式。写法与无参构造写法一样,但是,默认的无参构造函数不会进行初始化,而全缺省构造函数对其进行了初始化。
如下:
在这里插入图片描述

注意:

  • 不能写成Data d1();否则就成了函数声明
  • 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。

四、默认构造函数意义:

默认构造的三种形式:
在这里插入图片描述
总结:可以不传参数调用的都叫默认构造

1.问题引入:

执行下面代码:

class Data
{
public:
	void print() 
	{
		cout << "时间  " << _year <<"+" << _month << "+" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	d1.print();
	return 0;
}

在这里插入图片描述
可以发现,使用默认构造,变量都是随机值,并没有任何处理,这样说默认构造好像没有什么用啊!想要弄清楚这个问题,我们通过下面的学习。

2.内置类型和自定义类型

默认生成的构造函数对于:

  • 内置类型(如int,double,指针等系统定义的类型): 不做处理
  • 自定义类型(自己定义的类型,如自己定义的):会对其进行处理,会调用自定义类型的类中的构造函数,如果没有 ,那么也还是随机值。

如:定义了一个栈类,使用两个栈实现队列,这个队列中的数据类型有Stack类型的,当调用默认构造时,Stack类型的变量会去栈类中调用构造函数,为其赋初值。有点绕,但是写一份代码太麻烦了。(仅供自己理解)

五、补充

其实这种定义并不方便,更好的做法是,int就默认赋值0,double就默认赋值0.0等等。
所以在C++11中做出了补丁,也就是允许在类在声明变量时给缺省值。

class Data
{
public:
	void print() 
	{
		cout << "时间  " << _year <<"+" << _month << "+" << _day << endl;
	}
private:
	int _year =1;
	int _month =1;
	int _day =1;
};

变动的地方也就在这里:如下
在这里插入图片描述
我们前面说过,类中的成员变量都是声明,那么我们现在这样写是不是就是定义了呢?答案是它还是声明,并不是定义,没有开空间。

使用这种写法,我们在以后的声明中可以直接不写构造函数,让编译器默认自己生成构造函数。
例如:

class Data
{
public:
	void print() 
	{
		cout << "时间  " << _year <<"+" << _month << "+" << _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

int main()
{
	Data d1;
	d1.print();
	return 0;
}

在这里插入图片描述

总结:内置类型赋予了缺省值,或者成员变量都是自定义类型,可以直接使用默认的无参构造。

后续补充!

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

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

相关文章

Vue3 源码解读系列(九)——依赖注入

依赖注入 依赖注入用于祖先组件向后代组件传递数据。 特点&#xff1a; 祖先组件不需要知道哪些后代组件在使用它提供的数据。 后代组件也不需要知道注入的数据来自哪里。 /*** provide 的实现*/ function provide(key, value) {let provides currentInstance.provides // 当…

量子计算+物流!“最后一英里”配送难题Unisys成功实时决策

&#xff08;图片来源&#xff1a;网络&#xff09; 此前&#xff0c;供应链行业一直致力于手工操作&#xff0c;严重依赖于纸质系统。后来随着客户需求的不断变化&#xff0c;这种传统方法逐渐显出不足之处。供应链行业正在迅速转向现代化&#xff0c;采用自动化和数据驱动的…

【开源】基于微信小程序的音乐平台

项目编号&#xff1a; S 055 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S055&#xff0c;文末获取源码。} 项目编号&#xff1a;S055&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示 四、核心代码4.1 查询单首…

redis的一些操作

文章目录 清空当前缓存和所有缓存配置内存大小&#xff0c;防止内存饱满设置内存淘汰策略键过期机制 清空当前缓存和所有缓存 Windows环境下使用命令行进行redis缓存清理 redis安装目录下输入cmdredis-cli -p 端口号flushdb 清除当前数据库缓存flushall 清除整个redis所有缓存…

关于一些网络的概述

语义分割网络是一种基于深度学习的计算机视觉技术,它能够将图像中的每个像素分配给特定的类别,从而实现对图像中不同对象的精确识别和定位。近年来,随着深度学习技术的不断发展,语义分割网络在各个领域都取得了显著的进展。 早期的语义分割网络主要采用全卷积神经网络(FC…

大数据分析仓库Kylin

一、Kylin 定义 Apache Kylin 是一个开源的分布式分析引擎&#xff0c;提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析能力以支持超大规模数据&#xff0c;最初由 eBay 开发并贡献至开源社区。它能在亚秒内查询巨大的 Hive 表。 二、Kylin 架构 A、REST Server 是应用程序…

操作系统基础操作

操作系统的启动 体系结构概念 CPU、I/O、内存-通过总线连接 操作系统一开始存放时没有放在内存里&#xff0c;而是当在DISK中&#xff0c;由BIOS提供相应支持 DISK&#xff1a;存放OSBIOS&#xff1a;基本I/O处理系统&#xff08;计算机开机时可以让系统检测各种外设&#…

软文转化率如何提高,媒介盒子分享三大原则

决定软文推广的主要因素就在于软文内容&#xff0c;但是如何才能提高软文转化率呢&#xff1f;下面就让媒介盒子为你解答&#xff01; 一、 软文类型 软文类型按照推广目标划分主要分为品牌软文、产品软文、营销软文。 ● 品牌软文 品牌软文的目的在于扩大品牌对群众的影响力…

基于Vue+SpringBoot的桃花峪滑雪场租赁系统

项目编号&#xff1a; S 036 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S036&#xff0c;文末获取源码。} 项目编号&#xff1a;S036&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 游客服务2.2 雪场管理 三、数据库设…

SpringCloud微服务 【实用篇】| Eureka注册中心、Ribbon负载均衡

目录 一&#xff1a;Eureka注册中心 1. Eureka原理 2. 动手实践 ①搭建EurekaServer ②服务注册 ③服务发现 二&#xff1a;Ribbon负载均衡 1. 负载均衡原理 2. 负载均衡策略 3. 懒加载 一&#xff1a;Eureka注册中心 前面已经分析了&#xff0c;无论是SpringCloud还…

从0开始学习JavaScript--JavaScript中的集合类

JavaScript中的集合类是处理数据的关键&#xff0c;涵盖了数组、Set、Map等多种数据结构。本文将深入研究这些集合类的创建、操作&#xff0c;以及实际应用场景&#xff0c;并通过丰富的示例代码&#xff0c;帮助大家更全面地了解和应用这些概念。 数组&#xff08;Array&…

【Java】NIO概述

本文主要介绍Java的IO。 这里主要按类的操作方式和操作对象对JavaIO进行分类&#xff0c;方便理解&#xff0c;后续使用时可以方便地查询。 一、操作方式分类 首先介绍几组概念&#xff1a; 字节流和字符流&#xff1a; 字节流&#xff1a;以字节为单位&#xff0c;每次次读…

【高级网络程序设计】Week2-3 HTML

一、The Basics 1. HTML&HTML file HTMLMarkup languageHyper Text Markup LanguageHTML fileText file with markup tags.htm/.html extension Create an html file Open an editor Type: <html><head><titile><body> Save it as .html Open i…

计算机网络——网络可靠性及网络出口配置

1. 前言&#xff1a; 学习目标&#xff1a; 1.了解链路聚合的作用 2. 了解ACL的工作原理 3. 了解NAT的工作原理和配置 2. 网络可靠性方案 网络可靠性是指网络在面对各种异常情况或故障时&#xff0c;能够维持正常运行和提供服务的能力。这包括防止网络中断、减小数据丢失的可能…

vue3中使用全局自定义指令和组件自定义指令

这篇文章会教大家如何实现全局自定义指令和组件自定义指令 &#x1f4d3;全局自定义指令和组件自定义指令的区别&#xff0c;除了写法不同和作用不同&#xff0c;其他的包括生命周期的使用方法都是一致的&#xff0c;全局自定义指令在main.ts中注册后整个项目都可以使用&#x…

dvwa-command injection 代码审计(超详细逐行审计)

dvwa-command injection 代码审计 low <?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target $_REQUEST[ ip ];// Determine OS and execute the ping command.if( stristr( php_uname( s ), Windows NT ) ) {// Windows$cmd shell_exec( ping . $target );}…

Parallel Diffusion Models of Operator and Image for Blind Inverse Problems

盲逆问题算子和图像的并行扩散模型 论文链接&#xff1a;https://arxiv.org/abs/2211.10656 项目链接&#xff1a;https://github.com/BlindDPS/blind-dps Abstract 在正向算子已知的情况下(即非盲)&#xff0c;基于扩散模型的逆问题求解器已经展示了最先进的性能。然而&…

linux md5sum计算hash指令

在soc启动&#xff0c;验证镜像签名时&#xff0c;会计算文件的hash值&#xff0c;确保文件未被修改&#xff0c;md5sum可以计算&#xff0c;有256,512位的的其他指令&#xff0c; 如下&#xff0c;计算文件hash值。

@PostConstruct虽好,请勿乱用

1.问题说明 在日常的业务开发中&#xff0c;有时会利用PostConstruct在容器启动时执行一些任务。例如&#xff1a; PostConstruct public void init(){System.out.println("service 初始化..............."); }一般情况这没什么问题&#xff0c;但最近一个同事在做…

Android加固为何重要?很多人不学

为什么要加固&#xff1f; APP加固是对APP代码逻辑的一种保护。原理是将应用文件进行某种形式的转换&#xff0c;包括不限于隐藏&#xff0c;混淆&#xff0c;加密等操作&#xff0c;进一步保护软件的利益不受损坏。总结主要有以下三方面预期效果&#xff1a; 1.防篡改&#x…