构造函数详解

目录

  • 类的6个默认成员函数
    • 构造函数
      • 概念
      • 特性
        • 构造函数语法
          • 无参初始化
          • 有参初始化
      • 构造函数特征总结

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录

类的6个默认成员函数

如果一个类中什么成员都没有,简称为空类。
空类中并不是什么都没有,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数

默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数(没写编译器就会默认生成,有点像缺省参数,不传值就自动帮你传默认的缺省值)

默认成员函数分为一下6种

构造函数:完成初始化
析构函数:完成清理(类似数据结构实现的Destroy函数)
拷贝构造函数:使同类对象初始化创建对象
赋值重载函数:把一个对象赋值给另一个对象
取地址重函数:对普通对象和const对象取地址

构造函数

概念

对于Date类,可以通过 Init 公有方法给对象设置日期,但如果每次创建对象时都调用该方法设置
信息,会有点麻烦,那能否在对象创建时,就将信息设置进去呢?

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证
每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任
务并不是开空间创建对象,而是初始化对象(特别注意构造函数不是开空间)

构造函数语法
无参初始化
class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 2;
		_day = 3;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
}

上面类中的函数Date函数名与类名Date相同,并且没有返回值(函数名之前没有int等返回类型)
在这里插入图片描述
类中的函数可以构成函数重载,即函数名相同,但是传入的参数类型不同…

class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 2;
		_day = 3;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2(2024, 5, 7);
	d2.Print();
}

在这里插入图片描述
有人会注意到Date d1不像Date d2那样有括号,那可不可以在Date d1中加入括号变成Date d1()表示无参呢?
在这里插入图片描述
其实是不行的,原因是Date d1()会和函数声明区分不开,因为函数声明可能会是无参的函数比如Date func(),Date func()的功能可能就只是打印一句话,所以不需要传参

而Date d2(2024, 5, 7)不会报错的原因是因为对于需要传参的函数声明时是需要写出函数类型的,比如Date func(int…)

C++规定对象实例化的时候必须要调用默认构造函数

当我们屏蔽掉Date的时候就会报错
在这里插入图片描述

有参初始化
class Date
{
public:
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d2(2024, 5, 7);
	d2.Print();
}

在这里插入图片描述
由于默认构造函数比较特殊,所以写法和之前学习的类中的函数有些不同,比如就不能像下面这样去写

class Date
{
public:

	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d2;
	d2.Date(2024,5, 7);
	d2.Print();
}

这个代码的意思是因为类名为Date,所以创建一个对象d2,因为类中有一个函数为Date,所以想去调用d2中的函数Date,但是最后的结果就会出错
在这里插入图片描述
构造函数是可以支持缺省参数的

class Date
{
public:
	/*Date()
	{
		_year = 1;
		_month = 2;
		_day = 3;
	}*/
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}
	Date(int year=2024, int month=5, int day=7)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2(1);
	d2.Print();
}

在这里插入图片描述
但当把d2括号中传入的参数去掉后,就报错了
在这里插入图片描述

class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 2;
		_day = 3;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}
	Date(int year=2024, int month=5, int day=7)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2(1);
	d2.Print();
}

此外当取消屏蔽Date()时,有人可能会觉得Date()会和Date(int year=2024, int month=5, int day=7)构成函数重载,实际上也是可以的
但是因为Date(int year=2024, int month=5, int day=7)是缺省参数,会在使用的时候和Date()产生歧义,所以一般情况下都不会把这两个函数都同时写出来
在这里插入图片描述

构造函数特征总结

  1. 函数名与类名相同。
  2. 无返回值(不是像void,是根本不需要写返回类型)
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载。
  5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦
    用户显式定义编译器将不再生成
    编译器生产的默认构造函数有时并没有初始化
    这是因为C++将数据类型分为内置类型和自定义类型
    内置类型的含义就是语言自身定义的类型,比如int/char/double/指针…
    自定义类型就是自己定义的一些类型,比如struct/class
    C++规定默认生产的构造函数对于内置类型不做处理,而自定义类型会处理(有些编译器可能也会对内置类型进行处理,但是并不是C++规定的)

但是事实上自定义类型到最后都是内置类型具体如下,因为自定义类型内部一定是由内置类型去构成的,比如下面的代码,找到最后的class B,里面只有一个内置类型 int c,而这个内置类型int c最终还是需要我们去初始化

class B
{
	int c;
};
class A
{
public:

	B _b;
private:
	int a;
	int b;
};

在这里插入图片描述

class A
{
public:
	A()
	{
		cout << "A()" << endl;
		_a = 0;
	}
private :
	int _a;
};

class Date
{
public:
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
	A _aa;
};
int main()
{
	Date d2;
	d2.Print();
}

这个代码中Date对于自定义类型A会去调用他的默认构造函数,所以最后打印出A(),而内置类型没有调用,所以出现的是随机值
在这里插入图片描述
通过调试也可以看出,_aa的值是完成了初始化的
在这里插入图片描述

而在C++11后,这个语法可以支持在声明的位置给缺省值,但是要注意这不是定义,只是给了缺省值,有了缺省值,就会用给的缺省值去初始化
在这里插入图片描述
在这里插入图片描述

  1. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
    注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为
    是默认构造函数(或者说是可以不需要传参就能调用构造函数的就是默认构造函数)
    无参构造函数、全缺省构造函数以及编译器默认生成的构造函数只能有一个存在(无参构造和全缺省构造同时存在会有歧义)
class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/"<<_day << endl;
		
	}
private:
	int _year=1;
	int _month=1;
	int _day=1;
};
int main()
{
	Date d2;
	d2.Print();
}

在这里插入图片描述

这段代码的报错为不存在默认构造函数或,没有合适的默认构造函数可用

这是因为当我们没有自己写默认构造函数的时候,编译器回去自己创造一个默认构造函数,而当我们写了默认构造函数的时候,编译器就会去调用我们写的默认构造函数,代码中我们写了一个带参的默认构造,所以编译器不会去自己创造一个默认构造函数,

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电动汽车与 PLM:下一代转型的结合

汽车电气化是汽车行业持续变革的驱动力&#xff0c;因此电动汽车 (EV) 行业成为当今最令人兴奋、最相关和最必要的创新领域之一。快速且有利可图地设计电动汽车及其零部件&#xff0c;同时使其受到消费者的青睐&#xff0c;是一项艰巨的挑战。因此&#xff0c;电动汽车行业企业…

【人民网注册_登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

一个API接口对接ChatGPT3.5/4.0,Claude3,文心一言,通义千问,智谱AI等多款AI模型,打造属于自己的AI应用

今天我要给大家介绍团队的最新项目——一个集成了ChatGPT-3.5/4.0、Claude3、文心一言、通义千问、智谱AI等多个AI模型的API模型聚合平台。仅需使用一个接口就可以对接所有AI模型 为什么要创建这个平台&#xff1f; 随着不同的AI模型陆续问世&#xff0c;每个模型都有其独特…

容器组件:Column ,Row(HarmonyOS学习第四课【4.1】)

容器组件-Column Column 容器组件是沿垂直方向布局的容器。该组件从APIVersion7开始支持从API version 9开始&#xff0c;该接口支持在ArkTs,卡片中使用。其可以包含子组件 Column(value?: {space?: string | number}) 参数 space 参数类型string | number 是否必填&am…

vuerouter声明式导航

声明式导航-跳转传参数 1.查询参数传参 语法&#xff1a;to /path?参数名值 2.对应页面组件接受传来的值 $router.query.参数名 2.动态路由传参 1.配置动态路由 2.配置导航连接 to/path/参数值 3.对应页面组件接收传递过来的值 #route.params.参数名 多个参数传递&…

Linux —— 线程

Linux —— 线程 什么是线程Linux如何实现线程Winodws如何实现线程使用一下线程pthread_create函数原型参数说明返回值 如何解决 ps -aL 查看线程线程为什么轻量 我们今天进入线程的学习&#xff1a; 什么是线程 我们先来了解一个笼统的概念&#xff1a;简单来说&#xff0c;…

如何利用代理IP高效采集全球热点,赋能短视频创作?

如何利用代理IP高效采集全球热点&#xff0c;赋能短视频创作&#xff1f; 一、摘要二、代理IP1. 什么是代理IP&#xff1f;2. 代理IP的分类3. 代理的重要性 三、如何选择可靠的代理IP服务商&#xff1f;四、IPIDEA代理IP简介1.IPIDEA简介2.IPIDEA的优势 五、获取代理IP1. 注册平…

618平价好物哪些比较值得入手?2024年618平价好物选购清单

距离下一次大型促销活动618仅有一个半月的时间了&#xff0c;相信许多人已经开始为购物清单做准备了。在这个充满诱惑的购物季&#xff0c;你是否已经找到了那些让你心动的好物呢&#xff1f;今天&#xff0c;我想和大家分享一下我之前购买并使用过的一些优质商品&#xff0c;它…

【软件安装】vmware虚拟机安装完整教程(15.5版本)

安装包-百度网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1zwYeRVdp1TM75JIctkWqVA?pwd6666 提取码&#xff1a;6666 1、去BIOS里修改设置开启虚拟化设备支持&#xff08;这一步必须要进行&#xff09; 网址&#xff1a;https://jingyan.baidu.com/article…

驱动丹佛斯比例电磁铁放大器

驱动丹佛斯比例电磁铁是一种用于实现对液压系统连续且精确控制的通电带磁性装置。比例阀由直流比例电磁铁和液压阀两部分组成。其中&#xff0c;比例电磁铁是其核心部件&#xff0c;负责将输入的电信号转换成力和位移输出&#xff0c;从而控制液压阀的工作状态。比例电磁铁通过…

ROS2安装

实习上班就是摸鱼&#xff01;学习一下ROS2吧 由于ROS存在较多的不足&#xff0c;所以转战ROS2了&#xff0c;最主要的区别在于在ROS2中&#xff0c;将ROS中的主节点给去掉了 http://fishros.com/d2lros2/#/humble/chapt1/get_started/2.ROS%E4%B8%8EROS2%E5%AF%B9%E6%AF%94…

2024最新独立版校园跑腿校园社区小程序源码+附教程 适合跑腿,外卖,表白,二手,快递等校园服务

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 后台php&#xff0c;前端uniapp可以二次开 2024最新独立版校园跑腿校园社区小程序源码附教程 测试环境&#xff1a;NginxPHP7.2MySQL5.6 多校版本&#xff0c;多模块&#xff0c;适…

果园游戏功能介绍

果园游戏通常围绕种植、管理、收获果实以及与朋友互动等元素设计。以下是果园游戏可能具备的一些功能介绍&#xff1a; 植物种植和养护&#xff1a; 玩家可以选择种植各种水果或植物&#xff0c;每种植物都有自己的生长周期和特点。需要定期给植物浇水、施肥、除草、除虫等&am…

可道云teamOS企业网盘实用插件介绍:实时在线流程图编辑与分享,用在线流程图打造数字化工作流程

在使用企业网盘用于日常办公的情况下&#xff0c;有一些实用的在线小工具能为团队效率和协作带来一定的提升。 今天要给大家介绍的可道云teamOS的在线画流程图&#xff0c;是很值得介绍的一个在线工具。 在线流程图&#xff1a;直观展示&#xff0c;高效便捷 以往我们想要梳理…

面试中算法(金矿)

有一位国王拥有5座金矿&#xff0c;每座金矿的黄金储量不同&#xff0c;需要参与挖掘的工人人数也不同。 例如&#xff0c;有的金矿储量是5ookg黄金&#xff0c;需要5个工人来挖掘;有的金矿储量是2ookg黄金&#xff0c;需要3个工人来挖掘...... 如果参与挖矿的工人的总数是10。…

Linux部署

先把需要的东西准备好&#xff1a; 第一步解压tomcat&#xff1a; tar -zxvf apache-tomcat-8.5.20.tar.gz 第二步解压jdk: tar -zxvf jdk-8u151-linux-x64.tar.gz 第三步配置Java环境变量&#xff1a; vim /etc/profile 把下面代码放进去&#xff1a; export JAVA_HOME/root…

红队攻防|拿下服务器root权限

0x00前言 分享一个简单的项目&#xff0c;小有坎坷但仍旧几乎畅通无阻的最终拿下root权限。 先说重要的事情&#xff1a; 如有漏码少码导致能定位目标请各位师傅手下留情&#xff0c;后台留言提醒必有红包重谢&#xff01; 0x01信息收集 过程略&#xff0c;收集到目标的主站…

java基础之面向对象的思想

一、面向对象和面向过程的编程思想对比 面向过程&#xff1a;是一种以过程为中心的编程思想&#xff0c;实现功能的每一步&#xff0c;都是自己实现的&#xff08;自己干活&#xff09;。 面向对象&#xff1a;是一种以对象为中心的编程思想&#xff0c;通过指挥对象实现具体的…

ue5地编模块学习记录

ue5网站功能3d溜溜网下载模型https://anyconv.com/max-to-fbx-converter/3dmax转换fbx模型解决问题记录 一、光源 搜索光源搜索不到的时候可以点击 窗口> 对场景内的光照进行处理 二、认识节点 在UE5中&#xff0c;Depth Fade节点通常用于在材质中实现深度淡化效果&#…

【linux系统学习教程 Day02】网络安全之Linux系统学习教程,管道,文件内容统计,过滤排序,去重,目录介绍

1-4 管道 管道符号&#xff1a; | &#xff0c;可以将前面指令的执行结果&#xff0c;作为后面指令的操作内容。 ## 比如过滤ip地址 ip addr | tail -4 | head -1 解释一下就是先执行 ip addr ,得到的结果当做 tail -4 的输入&#xff0c;意思就是查看ip addr 结果的后四行内容…