当前位置: 首页 > news >正文

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;
}

二、构造函数的特性

        再次强调,开辟空间不是构造函数做的事。虽然构造函数叫做构造,但构造函数并不用来开空间创建对象,而是用来初始化对象的

  1.  函数名与类名相同。
  2. 无返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数支持缺省参数。
  5. 构造函数支持重载  。一个类中可以有多个构造函数它们之间构成函数重载。
  6. 如果类中没有显式定义构造函数,则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. 构造函数是什么&#xff1f; 2. 为什么C要引入构造函数&#xff1f; 3. 怎么用构造函数&#xff1f; 3.1 创建构造函数 3.2 调用构造函数 二、构造函数的特性 三、构造函数对成员变量初始化 0. 对构造函数和成员变量分类 1. 带参构造函数对成员变量初始化 2. …...

Swing程序设计(5)绝对布局,流布局

文章目录 前言一、布局管理器二、介绍 1.绝对布局2.流布局总结 前言 Swing窗体中&#xff0c;每一个组件都有大小和具体的位置。而在容器中摆放各种组件时&#xff0c;很难判断其组件的具体位置和大小。即一个完整的界面中&#xff0c;往往有多个组件&#xff0c;那么如何将这…...

linux基础知识之文件系统 df/du/fsck/dump2fs

du du [选项][目录或者文件名] -a 显示每个子文件等磁盘占用量&#xff0c;默认只统计子目录的磁盘占用量 -h 使用习惯单位显示磁盘占用量&#xff0c;如KB&#xff0c;MB或者GB -s 统计总占用量&#xff0c;不列出子目录和文件占用量 面向文件 du -a 16 ./.DS_Store 8 ./requi…...

华为云云耀云服务器L实例评测|Elasticsearch的Docker版本的安装和参数设置 端口开放和浏览器访问

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

8章:scrapy框架

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

软件工程与计算总结(二)软件工程的发展

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

Appium开发

特点 开源免费支持多个平台 IOS(苹果)、安卓App的自动化都支持 支持多种类型的自动化 支持苹果、安卓应用原生界面的自动化支持应用内嵌网络视图的自动化支持手机浏览器(Chrome)中的web网站自动化支持flutter应用的自动化 支持多种编程语言 像selenium一样&#xff0c;可以用多…...

EGL函数翻译--eglInitialize

EGL函数翻译–eglInitialize 函数名 EGLBoolean eglInitialize(EGLDisplay display,EGLInt* major,EGLInit* minor); 参数描述 参数display: EGL要初始化的显示连接。 参数major: 输出EGL的主版本号&#xff1b;参数可为空。 参数minor: 输出EGL的次版本号&#xff1b;参数可…...

二项分布以及实现

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

css自学框架之幻灯片展示效果

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

坦克世界WOT知识图谱三部曲之爬虫篇

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

Idea上传项目到gitlab并创建使用分支

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

3D孪生场景搭建:参数化模型

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

最短路径专题6 最短路径-多路径

题目&#xff1a; 样例&#xff1a; 输入 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 思路&#xff1a; 根据题意&#xff0c;最短路模板还是少不了的&#xff0c; 我们要添加的是&#xff0c; 记录各个结点有多少个上一个结点走动得来的…...

【Linux】Linux常用命令—文件管理(上)

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…...

【Python】基于OpenCV人脸追踪、手势识别控制的求生之路FPS游戏操作

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

约束优化算法(optimtool.constrain)

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

如何查看postgresql中的数据库大小?

你可以使用以下命令来查看PostgreSQL数据库的大小&#xff1a; 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;这将返回一个表格&#xff0…...

使用python-opencv检测图片中的人像

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

项目进展(三)-电机驱动起来了,发现了很多关键点,也遇到了一些低级错误,

一、前言 昨天电机没有驱动起来&#xff0c;头发掉一堆&#xff0c;不过今天&#xff0c;终于终于终于把电机驱动起来了&#xff01;&#xff01;&#xff01;&#xff01;&#xff0c;特别开心&#xff0c;哈哈哈哈&#xff0c;后续继续努力完善&#xff01;&#xff01;&…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

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))…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...