C++ 类和对象篇(四) 构造函数
目录
一、概念
1. 构造函数是什么?
2. 为什么C++要引入构造函数?
3. 怎么用构造函数?
3.1 创建构造函数
3.2 调用构造函数
二、构造函数的特性
三、构造函数对成员变量初始化
0. 对构造函数和成员变量分类
1. 带参构造函数对成员变量初始化
2. 无参构造函数对成员变量初始化
拓展. 内置类型成员在编译器生成的无参构造函数中不初始化的缺陷
四、默认构造函数
1. 什么是默认构造函数?
2. 编译器生成的无参构造函数
3. 保证只有一个默认构造函数
一、概念
1. 构造函数是什么?
构造函数是一个特殊的成员函数用来初始化成员变量,函数名和类名相同,使用实例化对象时由编译器自动调用,并且在对象整个生命周期内只调用一次。
2. 为什么C++要引入构造函数?
怎么对类中的成员变量进行初始化?写一个成员函数专门用来初始化成员变量?但如果忘记调用了怎么办?为解决类初始化和忘记初始化类的问题,能不能在创建对象时就自动完成初始化的动作呢?
举个小例子: 有以下Date类: class Date { public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day; };如果要使用该Date类创建对象,必须通过Init公有方法给对象设置日期,否则成员变量都是随机值, 但每次创建对象时都调用该方法,这未免有点麻烦,那能否在对象创建的同时,就将信息设置进去呢?
为解决以上问题,C++中引入了构造函数:构造函数用于对象的初始化,在实例化对象时由编译器自动调用,保证了对象创建出来一定完成了初始化。虽然构造函数叫做构造,但构造函数并不用来开空间创建对象,而是用来初始化对象的。(也许构造函数更适合被称为初始化函数?)
3. 怎么用构造函数?
3.1 创建构造函数
创建时要注意构造函数特征:函数名与类名相同、无返回值。
构造函数主要分两类:无参构造函数、带参构造函数。
用以下例子来说明如何创建无参构造函数和带参构造函数: 创建时要注意构造函数特征:函数名与类名相同、无返回值。 class Date { public://1、无参构造函数Date(){}// 2.带参构造函数Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day; };
3.2 调用构造函数
实例化对象时编译器自动调用构造函数。
接上面的例子,演示如何调用无参构造函数和带参构造函数: int main() {// 自动调用无参构造函数Date d1;// 自动调用带参的构造函数Date d2(2023, 10, 1);return 0; }
注意:通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明。
如下不是在调用构造函数,而是在main函数中声明了一个函数名为d3函数,该函数无参,返回值为Date类型: int main() {//以下代码不是在创建对象,而是在声明d3函数,该函数无参,返回值为Date类型。Date d3();return 0; }
二、构造函数的特性
再次强调,开辟空间不是构造函数做的事。虽然构造函数叫做构造,但构造函数并不用来开空间创建对象,而是用来初始化对象的。
- 函数名与类名相同。
- 无返回值。
- 对象实例化时编译器自动调用对应的构造函数。
- 构造函数支持缺省参数。
构造函数支持重载 。一个类中可以有多个构造函数它们之间构成函数重载。 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数。一旦用户显式定义构造函数,编译器将不再生成无参的默认构造函数:
![]()
三、构造函数对成员变量初始化
0. 对构造函数和成员变量分类
构造函数主要分两类:无参构造函数、带参构造函数。
成员变量主要分两类:内置类型(基本类型)、自定义类型。
内置类型就是语言提供的数据类型,如: int/char/double/…/指针;
自定义类型就是使用class/struct/union等定义的类型。
(注意:指针是内置类型,那自定义类型的指针当然也是内置类型。)
1. 带参构造函数对成员变量初始化
1.1 类型为内置类型的成员变量:
有多少参数就要传入多少对应的值,设置了参数的成员变量会被初始化对应值,没有设置参数的成员变量为随机值。
1.2 类型为自定义类型的成员变量:
a. 如果有默认构造函数,类型为自定义类型的成员变量会在实例化对象时自动被初始化:
看以下例子: 由于a是自定义类型A的实例,所以在实例化b对象时,会自动调用A的默认构造函数来初始化a。 class A{ public:A(){//A的默认构造函数cout << "A()被调用" << endl;} };class B{ public:B(int x = 10){ _x = x; } private:int x;A a; //自定义类型的成员变量//a是一个实例化的对象 };int main() {B b;return 0; }
在B的默认构造函数中没有显式调用A的默认构造函数。但由于a是自定义类型A的实例,所以在实例化B对象时,一开始就会自动调用A的默认构造函数来初始化a对象。
b. 但如果自定义类型的成员变量没有默认构造函数,必须在定义自定义类型的成员变量时进行初始化,否则该成员变量无法被创建:
总结:对于类中的自定义类型的成员变量在创建时就要调用该成员变量的构造函数进行初始化,否则该成员变量无法被创建。只有成员变量被创建,我们才能在构造函数中对其进行初始化。
2. 无参构造函数对成员变量初始化
2.1 类型为内置类型的成员变量:
对于编译器生成的或没有内容的无参构造函数不会对内置类型的成员变量进行初始化,所以其还是为随机值。
2.2 类型为自定义类型的成员变量:
对于类中的自定义类型的成员变量在创建时就要调用该成员变量的构造函数进行初始化,否则该成员变量无法被创建。只有成员变量被创建,我们才能在构造函数中对其进行初始化。
拓展. 内置类型成员在编译器生成的无参构造函数中不初始化的缺陷
编译器生成的无参构造函数不会对内置类型的成员变量进行初始化,所以其还是为随机值。
C++11中针对该缺陷,打了个补丁,即:
内置类型成员变量在类中声明时可以设置默认值。【这里设置的默认值实际上是在设置缺省值,因为我们只是在声明一个类,而不是在实例化一个对象。(可能有人会认为它是在初始化类,但其实它是在设置缺省值)】
四、默认构造函数
1. 什么是默认构造函数?
无参构造函数、全缺省构造函数、我们没写编译器生成的无参构造函数,都可以认为是默认构造函数。
2. 编译器生成的无参构造函数
2.0 没有构造函数时编译器会自动生成一个无参的构造函数
如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数。一旦用户显式定义构造函数,编译器将不再生成无参的默认构造函数。
2.1 编译器生成的无参构造函数作用
a. 用于对象的拷贝:创建新对象来拷贝旧对象时,首先要调用无参构造函数来初始化这个新对象,然后再把旧对象的所有成员变量拷贝到这个新的对象中。
MyClass a; // 这里会调用无参构造函数来初始化a MyClass b = a; // 这里会调用拷贝构造函数来初始化b //拷贝构造函数会首先调用无参构造函数来初始化新对象b,然后再把a的所有成员变量拷贝到这个新对象b中
b. 在类的继承中使用:在C++中,如果一个子类继承了父类,那么在创建子类的对象时,如果父类没有提供无参构造函数,编译器会自动生成父类的默认无参构造函数。如果父类没有默认无参构造函数,那么在创建子类的对象时会出现编译错误。
3. 保证只有一个默认构造函数
要注意的是在定义类时无参构造函数和全缺省构造函数二者只能取其一,虽然能同时存在,但是不传参数时编译器不知道该调用哪一个,这样就造成了歧义,编译时很有可能会报错,所以不建议同时写这两种构造函数。推荐构造全缺省的构造函数,省事:在传参个数方面,不用再对构造函数进行重载。
------------------------END-------------------------
才疏学浅,谬误难免,欢迎各位批评指正。
相关文章:

C++ 类和对象篇(四) 构造函数
目录 一、概念 1. 构造函数是什么? 2. 为什么C要引入构造函数? 3. 怎么用构造函数? 3.1 创建构造函数 3.2 调用构造函数 二、构造函数的特性 三、构造函数对成员变量初始化 0. 对构造函数和成员变量分类 1. 带参构造函数对成员变量初始化 2. …...

Swing程序设计(5)绝对布局,流布局
文章目录 前言一、布局管理器二、介绍 1.绝对布局2.流布局总结 前言 Swing窗体中,每一个组件都有大小和具体的位置。而在容器中摆放各种组件时,很难判断其组件的具体位置和大小。即一个完整的界面中,往往有多个组件,那么如何将这…...
linux基础知识之文件系统 df/du/fsck/dump2fs
du du [选项][目录或者文件名] -a 显示每个子文件等磁盘占用量,默认只统计子目录的磁盘占用量 -h 使用习惯单位显示磁盘占用量,如KB,MB或者GB -s 统计总占用量,不列出子目录和文件占用量 面向文件 du -a 16 ./.DS_Store 8 ./requi…...

华为云云耀云服务器L实例评测|Elasticsearch的Docker版本的安装和参数设置 端口开放和浏览器访问
前言 最近华为云云耀云服务器L实例上新,也搞了一台来玩,期间遇到各种问题,在解决问题的过程中学到不少和运维相关的知识。 本篇博客介绍Elasticsearch的Docker版本的安装和参数设置,端口开放和浏览器访问。 其他相关的华为云云…...

8章:scrapy框架
文章目录 scrapy框架如何学习框架?什么是scarpy?scrapy的使用步骤1.先转到想创建工程的目录下:cd ...2.创建一个工程3.创建之后要转到工程目录下4.在spiders子目录中创建一个爬虫文件5.执行工程setting文件中的参数 scrapy数据解析scrapy持久…...

软件工程与计算总结(二)软件工程的发展
本章开始介绍第二节内容,主要是一些历史性的东西~ 一.软件工程的发展脉络 1.基础环境因素的变化及其对软件工程的推动 抽象软件实体和虚拟计算机都是软件工程的基础环境因素,它们能从根本上影响软件工程的生产能力,而且是软件工程无法反向…...

Appium开发
特点 开源免费支持多个平台 IOS(苹果)、安卓App的自动化都支持 支持多种类型的自动化 支持苹果、安卓应用原生界面的自动化支持应用内嵌网络视图的自动化支持手机浏览器(Chrome)中的web网站自动化支持flutter应用的自动化 支持多种编程语言 像selenium一样,可以用多…...
EGL函数翻译--eglInitialize
EGL函数翻译–eglInitialize 函数名 EGLBoolean eglInitialize(EGLDisplay display,EGLInt* major,EGLInit* minor); 参数描述 参数display: EGL要初始化的显示连接。 参数major: 输出EGL的主版本号;参数可为空。 参数minor: 输出EGL的次版本号;参数可…...

二项分布以及实现
文章目录 前言所谓二项分布就是只会产生两种结果的概率 1.概念 前言 所谓二项分布就是只会产生两种结果的概率 1.概念 下面是一个二项分布的的theano实现 import numpy as np import theano import theano.tensor as T from theano.tensor.nnet import conv from theano.ten…...

css自学框架之幻灯片展示效果
这一节,我自学了焦点图效果(自动播放,圆点控制),首先看一下效果: 下面我们还是老思路,css展示学习三个主要步骤:一是CSS代码,二是Javascript代码,三是Html代码。 一、css代码主要如…...

坦克世界WOT知识图谱三部曲之爬虫篇
文章目录 关于坦克世界1. 爬虫任务2. 获取坦克列表3. 获取坦克具体信息结束语 关于坦克世界 《坦克世界》(World of Tanks, WOT)是我在本科期间玩过的一款战争网游,由Wargaming公司研发。2010年10月30日在俄罗斯首发,2011年4月12日在北美和欧洲推出&…...

Idea上传项目到gitlab并创建使用分支
Idea上传项目到gitlab并创建使用分支 1 配置git 在idea的setting中,找到git,配置好git的位置,点击Test按钮显示出git版本号,则说明配置成功。 2 项目中引入git Idea通过VCS,选择Create Git Repository 在弹出的对话框…...

3D孪生场景搭建:参数化模型
1、什么是参数化模型 参数化模型是指通过一组参数来定义其形状和特征的数学模型或几何模型。这些参数可以用于控制模型的大小、形状、比例、位置、旋转、曲率等属性,从而实现对模型进行灵活的调整和变形。 在计算机图形学和三维建模领域,常见的参数化模…...

最短路径专题6 最短路径-多路径
题目: 样例: 输入 4 5 0 2 0 1 2 0 2 5 0 3 1 1 2 1 3 2 2 输出 2 0->1->2 0->3->2 思路: 根据题意,最短路模板还是少不了的, 我们要添加的是, 记录各个结点有多少个上一个结点走动得来的…...

【Linux】Linux常用命令—文件管理(上)
创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 🔥c系列专栏:C/C零基础到精通 🔥 给大…...

【Python】基于OpenCV人脸追踪、手势识别控制的求生之路FPS游戏操作
【Python】基于OpenCV人脸追踪、手势识别控制的求生之路FPS游戏操作 文章目录 手势识别人脸追踪键盘控制整体代码附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 视频: 基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 手…...

约束优化算法(optimtool.constrain)
import optimtool as oo from optimtool.base import np, sp, pltpip install optimtool>2.4.2约束优化算法(optimtool.constrain) import optimtool.constrain as oc oc.[方法名].[函数名]([目标函数], [参数表], [等式约束表], [不等式约数表], [初…...

如何查看postgresql中的数据库大小?
你可以使用以下命令来查看PostgreSQL数据库的大小: SELECT pg_database.datname as "database_name", pg_size_pretty(pg_database_size(pg_database.datname)) AS size_in_mb FROM pg_database ORDER by size_in_mb DESC;这将返回一个表格࿰…...

使用python-opencv检测图片中的人像
最简单的方法进行图片中的人像检测 使用python-opencv配合yolov3模型进行图片中的人像检测 1、安装python-opencv、numpy pip install opencv-python pip install numpy 2、下载yolo模型文件和配置文件: 下载地址: https://download.csdn.net/down…...

项目进展(三)-电机驱动起来了,发现了很多关键点,也遇到了一些低级错误,
一、前言 昨天电机没有驱动起来,头发掉一堆,不过今天,终于终于终于把电机驱动起来了!!!!,特别开心,哈哈哈哈,后续继续努力完善!!&…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...