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…...
项目进展(三)-电机驱动起来了,发现了很多关键点,也遇到了一些低级错误,
一、前言 昨天电机没有驱动起来,头发掉一堆,不过今天,终于终于终于把电机驱动起来了!!!!,特别开心,哈哈哈哈,后续继续努力完善!!&…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...



