【C++--类和对象】构造函数析构函数

news2025/1/14 18:42:11

先来介绍一下类和对象中的六个默认成员函数:构造函数,析构函数,拷贝构造,赋值重载,普通对象取地址重载,const修饰对象取地址重载

这六类函数都是在我们没有显示定义的时候,编译器会自己生成的函数。而在我们显式定义以后编译器则不会处理。

构造函数和析构函数不是创建和销毁对象(对象存在于栈区,随着函数栈帧创建和销毁),而是初始化和清理工作。

构造函数 

一般是public的

是一种特殊的成员函数,

1、函数名与类名相同

2、没有返回值 不用写void

3、对象实例化的时候自动调用

4、支持重载

5、如果类里边没有显式定义构造函数编译器将会自动生成一个无参构造函数(默认构造函数),如果我们显式定义了编译器将不会生成默认构造函数

  • 默认构造

不传参就可以调用的函数就是默认构造函数,不一定是我们不写编译器自动生成,一共有三种情况。

默认构造函数的三种形式:无参构造函数,全缺省构造函数,编译器默认生成的构造函数都是默认构造函数。

这三者有且只能有一个(只能存在一个默认构造函数)

【1】调用无参构造:

#include <iostream>
using namespace std;
class Data
{
public:
    void Print()//会隐含一个this指针,指向对应的对象
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//我们不写,编译器自动生成一个
//无参构造函数
    Data()
    {
        cout<<"Data();"<<endl;
        _year=2023;
        _month=1;
        _day=1;
    }
//全缺省构造函数
    /*Data(int year=2020,int month=2,int day=2)
    {
        cout<<"Data(int year=2020,int month=2,int day=2);"<<endl;
        _year=year;
        _month=month;
        _day=day;
    }*/
private:
    int _year=1;
    int _month=1;
    int _day=1;

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

运行结果:

【2】调用全缺省构造

#include <iostream>
using namespace std;
class Data
{
public:
    void Print()//会隐含一个this指针,指向对应的对象
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//我们不写,编译器自动生成一个
//无参构造函数
    /*Data()
    {
        cout<<"Data();"<<endl;
        _year=2023;
        _month=1;
        _day=1;
    }*/
//全缺省构造函数
    Data(int year=2020,int month=2,int day=2)
    {
        cout<<"Data(int year=2020,int month=2,int day=2);"<<endl;
        _year=year;
        _month=month;
        _day=day;
    }
private:
    int _year=1;
    int _month=1;
    int _day=1;

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

运行结果:

【3】调用编译器自己生成的默认构造 (不写构造函数)

#include <iostream>
using namespace std;
class Data
{
public:
    void Print()//会隐含一个this指针,指向对应的对象
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//我们不写,编译器自动生成一个
//无参构造函数
    /*Data()
    {
        cout<<"Data();"<<endl;
        _year=2023;
        _month=1;
        _day=1;
    }*/
//全缺省构造函数
    /*Data(int year=2020,int month=2,int day=2)
    {
        cout<<"Data(int year=2020,int month=2,int day=2);"<<endl;
        _year=year;
        _month=month;
        _day=day;
    }*/
private:
    //给缺省值,当调用的是编译器自己生成的默认构造时会使用此缺省值
    int _year=1;    
    int _month=1;
    int _day=1;

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

运行结果:

1)如果不给缺省值,得到的是随机值(有的编译器也会进行处理,进行不同的初始化)

2)如果给了缺省值,则会按缺省值进行初始化对象

就相当于

C++规定:当我们不写构造函数时,编译器生成默认构造函数

【1】内置类型编译器不做处理,在声明的时候可以给缺省值,给了会进行初始化。(编译器不一定都会初始化内置类型成员,没有规定一定要进行处理) (就像上面写到的给_year,_month,_day缺省值,会进行对应的初始化处理)

【2】自定义类型会处理,会去调用它的默认构造。

可以算是c++的一个不足之处。(内置类型没有自动处理)

得出结论:

1、一般情况下,类里边有内置类型成员,默认构造函数需要我们自己写(否则会出现随机值的情况)

2、如果类里边全部都是自定义类型的成员,可以考虑让编译器自己生成(我们自己不用写,编译器调用默认构造函数)

3、如果类里边内置类型和自定义类型同时存在,内置类型不会处理,自定义类型一定会处理

(初始化的时候,有些编译器可能在没有写构造函数情况下,处理其中的内置类型,但这只是编译器的个性化行为)(所以必须得自己写默认构造)

注意:

class Data
{
public:
    Data()
    {
            
    }
    Data(int year=1,int month=1,int day=1)
    {
            
    }
    //两者可以同时存在,构成重载
    //但是在无参调用的时候,例如主函数中的Data d1;就会出现问题
    //因为不知道调用的是哪一个函数,两者都可以
private:
    int _year=1;
    int _month=1;
    int _day=1;
    //这种写法C++11标准下是支持的,这不是初始化,仅仅只是声明
    //给的默认缺省值,是给编译器生成默认构造函数用的    
};

构造函数的调用和普通函数也是有所区别的,

int main()
{
    //构造函数的调用
    Data d1;//对象不加列表
    Data d2(1,1,1);//对象+参数列表
    Data d2();//但是不可以这么写(在无参的情况下+括号)与函数声明冲突
    return 0;
}

析构函数

1、函数名在类名的前面加上~

2、无参无返回值 =》因此不能重载。

3、一个类只有一个,若显式定义系统不生成;若未显式定义,系统自动生成。

4、生命周期结束自动调用

函数的生命周期结束之后,自动调用;一般不会造成内存泄漏(学到后面可能会造成内存泄露,但智能指针可解决此类问题,后续再说)

  • 默认析构函数(编译器自动生成的析构函数):

a、内置类型成员不做处理

一般内置类型存储在栈上,不需要我们手动释放

b、自定义类型会调用他的析构函数

堆上的资源需要我们手动释放

1、需要写析构:一般有动态申请的资源,需要显式写析构函数(eg:栈 需要显式写析构函数 )

2、不需要写析构:

a、没有动态申请的资源(没有malloc之类)

eg:日期类 不需要写析构(都是内置类型,没有动态申请资源)

b、需要释放资源的成员都是自定义类型 这两种情况是需要释放的

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

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

相关文章

有什么好用的电容笔?apple pencil替代品推荐

近年来&#xff0c;电容笔越来越成为人们日常生活中常见的数码产品之一。电容笔的便捷性得到了消费者的认可。它逐渐取代无纸化书写。那么到底电容笔哪个品牌好呢&#xff0c;电容笔哪一款最好用呢&#xff0c;今天小编给大家总结几款市面好用的电容笔&#xff0c;让我们一起来…

什么是SPA单页面,优缺点是什么?如何实现?

目录 一、SPA的优点 二、SPA的缺点 三、SPA和MPA的区别 四、如何实现SPA应用 单页面应用程序&#xff08;SPA&#xff09;是一种基于Web的软件架构&#xff0c;其中只有一个页面&#xff0c;通过不同的路由和组件来展示不同的内容。SPA的应用非常广泛&#xff0c;例如在网页…

PCB layout在布线上的设计规范有哪些?

PCB Layout是一项技术活&#xff0c;也是经验活&#xff0c;良好的PCB Layout布线可帮助工程师确保最终的电路板性能、可靠性和制造质量&#xff0c;因此是很多电子工程师的学习重点&#xff0c;下面我们来盘点下PCB Layout关于布线的规范有哪些。 1、地管的引脚接地越短越好&a…

YOLO目标检测——路标数据集+已标注voc和yolo格式标签下载分享

实际项目应用&#xff1a;自动驾驶、视频监控和安防、物体识别和分类、城市规划和地理信息系统等等数据集说明&#xff1a;YOLO路标目标检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;图片格式为jpg&#xff0c;共900张图片&#xff0c;…

DPText-DETR: 基于动态点query的场景文本检测,更高更快更鲁棒 | 京东探索研究院

针对场景文本检测任务&#xff0c;近期基于DEtection TRansformer (DETR) 框架预测控制点的研究工作较为活跃。在基于DETR的检测器中&#xff0c;query的构建方式至关重要&#xff0c;现有方法中较为粗糙的位置先验信息构建导致了较低的训练效率以及性能。除此之外&#xff0c;…

Tomcat源码:CoyoteAdapter、Valve#invoke、ApplicationFilterChain

前文&#xff1a; 《Tomcat源码&#xff1a;启动类Bootstrap与Catalina的加载》 《Tomcat源码&#xff1a;容器的生命周期管理与事件监听》 《Tomcat源码&#xff1a;StandardServer与StandardService》 《Tomcat源码&#xff1a;Container接口》 《Tomcat源码&#xff1a…

在32位Windows中,DLL是如何导出的?

32 位 Windows 的设计者不必担心将所有内容压缩到 256KB 的内存中。由于 Win32 中的模块基于需求分页&#xff0c;因此你所要做的就是将整个映像映射到内存中&#xff0c;然后运行访问所需的部分。 DLL中的常驻名(resident name)和非常驻名(non-resident name)之间没有区别&am…

5.4 【MySQL】页目录

记录在页中按照主键值由小到大顺序串联成一个单链表&#xff0c;如果我们想根据主键值查找页中的某条记录&#xff0c;可以这样查询&#xff1a; SELECT * FROM page_demo WHERE c1 3; 我们平常想从一本书中查找某个内容的时候&#xff0c;一般会先看目录&#xff0c;找到需…

Docker配置阿里云镜像加速器

Docker配置阿里云镜像加速器 《Docker安装详细步骤》&#xff1a;Docker安装详细步骤_周十一.的博客-CSDN博客、 在前面博文已经介绍了docker 的安装&#xff0c;因为某些原因&#xff0c;我们下载镜像比较慢&#xff0c;今天给大家介绍一下&#xff0c;如何配置阿里云的镜像加…

解决Ubuntu无法安装pycairo和PyGObject

环境&#xff1a;虚拟机Ubuntu20.04&#xff0c;vscode无法安装pycairo和PyGObject 虚拟机Ubuntu20.04&#xff0c;vscode中运行Anaconda搭建的vens 的Python3.8.10 首先在vscode中点击ctrlshiftp&#xff0c;选择Python3.8.10的环境&#xff0c;自动激活Python 最近在搞无人…

在Linux和Windows上安装seata

1 前言 官网地址&#xff1a;https://seata.io/ 源码地址&#xff1a;https://github.com/seata/seata 官网手册&#xff1a;https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html Seata&#xff0c;一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简…

STM32CubeProgrammer 用ST-LINK不能烧录 解决方法

如下图所示&#xff0c;连接ST-LINK后可以认出Serial number&#xff0c;点击Connect后&#xff0c;显示“Error : Data read failed”&#xff0c;点击Download后&#xff0c;显示“Error: failed to download Segment[0]”。 此为正常现象&#xff0c;因为芯片加密&#xff0…

docker 容器编排工具 docker-compose从0到精通

compose简介 Docker-Compose 项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose 项目由 Python 编写&#xff0c;调用 Docker 服务提供的API来对容器进行管理。因此&#xff0c;只要所操作的平台支持 Docker API&#xff0c;就可以…

redis高可用之主从复制、哨兵模式、集群的概述及部署

目录 redis集群有三种模式 一、主从复制 1、主从复制的概念 2、主从复制的作用 3、主从复制的流程 4、主从复制的缺陷 5、搭建redis主从复制 二、redis 哨兵模式 1、哨兵模式的概念 2、哨兵模式的作用 3、故障转移机制 4、搭建Redis 哨兵模式 三、redis集群 1、r…

iOS开发Swift-12-列表UI,TableViewController,动态响应Button勾选-待办事项App(1)

1.创建新项目 为项目添加图标 2.将Table View Controller添加到界面中 将箭头移动到Table View上来,代表它是首页(根页面).选中ViewController,点击Delete,对它进行删除.将代码ViewController.swift也删除掉. 新建一个Cocoa Touch Class. 将TableViewController的cla…

记LGSVL Map Annotation(1) LGSVL本地编译记录、安装

主要的编译参考来着官方文件 Unity安装 安装unity hub 安装2020.3.3f1在unity hub上 但是我发现没有2020.3.3f1&#xff0c;只有2020.3.3f1c1&#xff0c;其实c1就是中国版&#xff0c;没有什么影响 GIT安装 安装GIT安装Git LFS验证git-lfs(输出Git LFS initialized就&am…

【linux】权限管理 详解(文件/访问者/目录 权限、权限指令、粘滞位... ...)

文章目录 权限的概念linux 权限管理文件访问者的类型&#xff08;用户&#xff09;文件类型和访问权限文件类型访问权限 文件权限值的 表示方法文件权限的 设置方法chmodchownchgrpumaskfilesudo 分配权限 目录的权限粘滞位注意 权限的概念 linux中有两种用户: 超级用户&…

Jeecg-Boot /jeecg-boot/jmreport/qurestSql接口sql注入漏洞复现

一、Jeecg-Boot介绍 JeecgBoot 是一款基于代码生成器的低代码开发平台&#xff01;前后端分离架构 SpringBoot2.x&#xff0c;SpringCloud&#xff0c;Ant Design&Vue&#xff0c;Mybatis-plus&#xff0c;Shiro&#xff0c;JWT&#xff0c;支持微服务。强大的代码生成器让…

淘宝整店商品列表信息API接口介绍

淘宝整店商品列表信息API接口&#xff08;Taobao whole store product list information API interface&#xff09;是在开放性API接口的基础之上&#xff0c;根据淘宝官方平台提供的以互联网为发展渠道的电子商务服务&#xff0c;通过数据整合与共享&#xff0c;抽象开发出来的…

java企业数据管理系统

项目介绍 此项目为企业数据管理系统的后端部分&#xff0c;前端部分请参考vue-admin&#xff0c;项目实现了菜单管理、用户管理、角色管理和权限管理四个基础模块&#xff0c;前端菜单管理结合动态路由可自由添加菜单。结合Shiro权限管理实现了菜单和按钮的权限控制。 ❝ 前端…