c++------类和对象(下)包含了this指针、构造函数、析构函数、拷贝构造等

文章目录

  • 前言
  • 一、this指针
    • 1.1、this指针的引出
    • 1.2、 this指针的特性
  • 二、类的默认的六个构造函数
    • 2.1、构造函数简述
    • 2.2构造函数
  • 三、析构函数
    • 3.1、析构函数引出
    • 3.2、特点:
  • 四、拷贝构造
    • 4.1、引入
    • 4.2、特征:
    • 4.3、默认拷贝构造函数
  • 总结


前言

在本节中,我将给大家介绍我们在学习C++中经常要用到的,this指针、类的六个默认成员函数、运算符重载等相关知识.

下面我会结合一个简单的类----日期类来介绍

后面需要时会补充相应的成员函数

class Date
{
public:void Display()//打印类对象中的内容{cout << _year << "-" << _month << "-" << _day << endl;}void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // 年int _month; // 月int _day; // 日
};

一、this指针

1.1、this指针的引出

int main(){Date d1, d2;d1.SetDate(2024,5,1);d2.SetDate(2024,6,1);d1.Display();d2.Display();return 0;}

当执行上述代码时,它的输出结果为:
在这里插入图片描述
下面的汇编不了解的,可以搜一下栈帧的创建和销毁,对今后的学习帮助很大
在这里插入图片描述

通过汇编我们可以看到,两次调用的SetDat函数地址相同(调用同一函数)

对于上述类,有这样的一个问题:
Date类中有SetDate与Display两个成员函数,函数体中没有关于不同对象的区分,那当d1调用SetDate函数时,该函数是如何知道应该设置s1对象,而不是设置d2对象呢?

C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

1.2、 this指针的特性

  1. this指针只能在“成员函数”的内部使用
  2. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。
  3. this指针是成员函数第一个隐含的指针形参,不需要用户
    传递.

将调用成员函数展开:
在这里插入图片描述

下面我们来证明一下this指针,本质上就是对象的地址:

为了更清晰的展示,我会简化用不到的代码

class Date
{
public:void Print_this(){cout << this << endl;//打印this指针}
private:int _year; // 年int _month; // 月int _day; // 日
};
int main()
{Date d1, d2;d1.Print_this();//cout << &d1 << endl;//如果和我们说的一样,那么打印结果应该两两相同d2.Print_this();cout << &d2 << endl;return 0;
}

结果:
在这里插入图片描述
可以看到this本质就是对象的地址。这就是隐藏的this指针,当然我们可以像学习C语言时知道一个结构体对象的地址使用“->”来进行成员变量的访问

class Date{public:void Display(){cout <<this-> _year << "-" <<this-> _month << "-" << this->_day << endl;}private:int _year; // 年int _month; // 月int _day; // 日};

二、类的默认的六个构造函数

在这里插入图片描述

恩师莫怪

2.1、构造函数简述

如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情况下,编译器都会自动生成6个默认成员函数。这些函数叫做构造函数。构造函数的任务是初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。
构造函数特点:

1.构造函数的名字和类名相同。
2.和其他函数不一样的是,构造函数没有返回类型。
3.类似于其他的函数,构造函数也有一个(可能为空的)参数列表和一个(可能为空的)函数体。
4.构造函数不能被声明成const 的。

需要特别注意的是,一个类可以拥有多个参数不同的构造函数,这些构造函数之间,向普通函数之间一样,可以构成函数重载

2.2构造函数

再贴一遍方便大家看

class Date
{
public:void Display()//打印类对象中的内容{cout << _year << "-" << _month << "-" << _day << endl;}void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // 年int _month; // 月int _day; // 日
};

对于Date类,可以通过SetDate公有的方法给对象设置内容,但是如果每次创建对象都调用该方法设置信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?我们上面说过:创建类的类型对象时由编译器自动调构造函数,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次。

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;
};
void TestDate()
{Date d1; // 调用无参构造函数Date d2(2024, 6, 1); // 调用带参的构造函数,用于初始化// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象Date d3();

如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
1.证明编译器默认生成的为无参的构造函数:

在这里插入图片描述

可以看到,我将自己写的构造函数屏蔽后,调用有参的构造函数是无法成功的,无参的并没有报错,这也说明编译器默认生成的为无参的构造函数。
2.证明当我们显示写出一个构造函数,编译器就不会在生成默认的构造函数:
在这里插入图片描述

我将带参的构造函数显示定义,d1无法调用无参的默认构造函数。
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且这两个默认构造函数不能同时存在。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数.

默认构造函数我们一般是为了处理自定义类型的成员变量

三、析构函数

3.1、析构函数引出

前面通过构造函数的学习,我们知道一个对象时怎么来的,那一个对象又是怎么没呢的?
析构函数:与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作(比如:类中定义的指针指向的空间的清理)

3.2、特点:

  1. 析构函数名是在类名前加上字符 ’~‘。
  2. 无参数无返回值。
  3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数
![class Date
{
public:~Date(){_year = 0;_month = 0;_day = 0;} Date(int year, int month, int day){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};
int main()
{Date d2(2024, 6, 1);return 0;
}

反汇编视角:
在这里插入图片描述

在上面的代码中,我并没有去显示调用析构函数,但是在程序执行结束时,编译器自动调用了,析构函数
这个也可以像构造函数一样测试,大家尝试一下

四、拷贝构造

4.1、引入

拷贝构造函数是构造函数的一种重载形式,它可以用来创建一个与已存在的对象一模一样的新对象。对于拷贝构造,它只有单个形参,且该形参必须是对本类类型对象的引用,因为要引用,所以要加const修饰。

4.2、特征:

1.拷贝构造函数的参数若使用传值方式编译器直接报错, 因为会引发无穷递归调用
2.若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数,对对象按 字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
3.编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了。

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1)//全缺省{_year = year;_month = month;_day = day;}// Date(const Date d)   // 错误--引发无穷递归Date(const Date& d)   // 正确写法_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);//也可以写成Date d2=d1return 0;
}

4.3、默认拷贝构造函数

像上面介绍的默认成员函数一样,当我们没有在类中写拷贝构造函数时,编译器会自动生成一个默认的拷贝构造。

系统生成的拷贝构造也会针对成员变量的内置类型和自定义类型做一个区分。对于内置类型的成员变量,编译器会按照被拷贝对象的内存存储字节序完成拷贝,就好比被拷贝的对象有3个int类型成员变量,占12字节内存,编译器会根据该对象的内存和成员初始值拷贝给新对象。

总结

本次我们介绍了,this指针、构造函数、析构函数、拷贝构造、等一些与类紧密关联的知识。
要将他们详细的介绍,所用篇幅过长,后续会出拓展版的

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

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

相关文章

Compose Multiplatform 1.6.10 发布,解释一些小问题, Jake 大佬的 Hack

虽然一直比较关注跨平台开发&#xff0c;但其实我很少写 Compose Multiplatform 的内容&#xff0c;因为关于 Compose Multiplatform 的使用&#xff0c;其实我并没在实际生产环境上发布过&#xff0c;但是这个版本确实值得一提&#xff0c;因为该版本包含&#xff1a; iOS Bet…

数据库(15)——DQL分页查询

DQL分页查询语法 SELECT 字段列表 FROM 表名 LIMIT 起始索引&#xff0c;查询记录数; 注&#xff1a;起始索引从0开始&#xff0c;起始索引&#xff08;查询页码-1&#xff09;*每页显示记录数。 如果查询的是第一页&#xff0c;可以省略起始索引。 示例&#xff1a;查询第一页…

【考研数学】概率论如何复习?跟谁好?

概率论一定要跟对老师&#xff0c;如果跟对老师&#xff0c;考研基本上能拿满分 概率论在考研试卷中占比并不大&#xff0c;其中&#xff1a; 高等数学&#xff0c;90分&#xff0c;约占比60%; 线性代数&#xff0c;30分&#xff0c;约占比20%; 概率论与数理统计&#xff0…

每日5题Day15 - LeetCode 71 - 75

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;71. 简化路径 - 力扣&#xff08;LeetCode&#xff09; class Solution {public String simplifyPath(String path) {Deque<String> stack new LinkedList…

mysql的增删查改(进阶)

目录 一. 更复杂的新增 二. 查询 2.1 聚合查询 COUNT SUM AVG MAX MIN 2.1.2 分组查询 group by 子句 2.1.3 HAVING 2.2 联合查询/多表查询 2.2.1 内连接 2.2.2 外连接 2.2.3 全外连接 2.2.4 自连接 2.2.5 子查询 2.2.6 合并查询 一. 更复杂的新增 将从表名查询到…

自动化办公01 smtplib 邮件⾃动发送

目录 一、准备需要发送邮件的邮箱账号 二、发送邮箱的基本步骤 1. 登录邮箱 2. 准备数据 3. 发送邮件 三、特殊内容的发送 1. 发送附件 2. 发送图片 3. 发送超文本内容 4.邮件模板内容 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即简单邮件传输协议…

【Qt秘籍】[009]-自定义槽函数/信号

自定义槽函数 在Qt中自定义槽函数是一个直接的过程&#xff0c;槽函数本质上是类的一个成员函数&#xff0c;它可以响应信号。所谓的自定义槽函数&#xff0c;实际上操作过程和定义普通的成员函数相似。以下是如何在Qt中定义一个自定义槽函数的步骤&#xff1a; 步骤 1: 定义槽…

三种字符串的管理方式

NSString的三种实现方式 OC这个语言在不停的升级自己的内存管理&#xff0c;尽量的让自己的 OC的字符串 问题引入 在学习字符串的过程中间会遇到一个因为OC语言更新造成的问题 例如&#xff1a; int main(int argc, const char * argv[]) {autoreleasepool {NSString* str1 …

网络原理——http/https ---http(1)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 网络原理 HTTP/HTTPS HTTP,全称为"超文本传输协议" HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议. 实际上,HTTP最新已经发展到 3.0 但是当前行业中主要使用的HT…

明日周刊-第12期

以前小时候最期待六一儿童节了&#xff0c;父母总会给你满足一个愿望&#xff0c;也许是一件礼物也许是一次陪伴。然而这个世界上其实还有很多儿童过不上儿童节&#xff0c;比如某些地区的小孩子&#xff0c;他们更担心的是能不能见到明天的太阳。 文章目录 一周热点航天探索火…

LeetCode-77. 组合【回溯】

LeetCode-77. 组合【回溯】 题目描述&#xff1a;解题思路一&#xff1a;回溯背诵版解题思路三&#xff1a;0 题目描述&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&a…

算法-对列表元素划分成两个和值最大且相等的子列表

现有私募基金发行一支特殊基金产品&#xff0c;该基金认购人数上限不超过 30 人&#xff0c; 募集总金额不超过 3000W&#xff0c;每个投资人认购金额不定。该基金只能将募集到的钱用于投资两支股票&#xff0c;且要求两支股票投资金额必须相同&#xff0c;且每位投资人的钱只能…

springboot报错:Failed to start bean ‘documentationPluginsBootstrapper‘

项目场景&#xff1a; springboot项目启动时报错 问题描述 具体报错信息&#xff1a; 可能原因分析&#xff1a; 1、SpringFox的版本与Spring Boot的版本不兼容。解决这个问题&#xff0c;你可能需要检查你正在使用的SpringFox和Spring Boot的版本&#xff0c;确保它们是兼容…

【Intro】Heterogeneous Graph Attention Network(HAN)

论文链接&#xff1a;https://arxiv.org/pdf/1903.07293 Abstract 异构性和丰富的语义信息给面向异构图的图形神经网络设计带来了巨大的挑战。 -> 一种基于分层注意的异构图神经网络&#xff0c;包括节点级注意和语义级注意。具体来说&#xff0c;节点级关注旨在学习节点…

GPT4o还没用上?落后一个月!

文章目录 一.Share官方网站&#xff1a;以一半的价格享受官网服务1.1 网址1.2 一些介绍和教学实战&#xff1a;1.3 主界面&#xff08;支持4o)&#xff1a;1.4 GPTS&#xff08;上千个工具箱任你选择&#xff09;&#xff1a;1.5 快速的文件数据分析&#xff08;以数学建模为例…

web前端三大主流框架指的是什么

web前端三大主流框架是什么&#xff1f;前端开发师的岗位职责有哪些&#xff1f;这边整理了相关内容供大家参考了解&#xff0c;请各位小伙伴随小编一起查阅下面的内容。 web前端三大主流框架 web前端三大主流框架是Angular、React、Vue。 1.Angular Angular原名angularJS诞生…

UnityAPI学习之Transform组件基本使用

目录 Transform组件 访问与获取 Transform的位置和旋转信息 Transform局部坐标和旋转信息的获取 Transform的缩放与正方向 缩放&#xff08;Scale&#xff09; 正方向 Transform相关的查找方法 销毁游戏物体 Transform组件 访问与获取 现在创建一个容器放置GrisGO物…

API接口通道如何设置?

API接口通道如何设置&#xff1f; 如果分站点的AI接口使用openai&#xff08;站点后台->系统配置->AI参数配置->AI接口&#xff09;&#xff0c;则需要在超管后台配置接口通道&#xff0c;其他方式则无需在超管后台配置接口通道 1、进入超管后台选择接口通道&#x…

一键批量转换,高效轻松管理:解锁不同格式图片统一处理新体验,让图片管理更高效

在信息爆炸的时代&#xff0c;图片管理成为了一个不容忽视的问题。我们时常面临各种格式的图片文件&#xff0c;不同的格式不仅增加了管理的难度&#xff0c;还可能导致兼容性问题。如何快速高效地管理不同格式的图片&#xff0c;成为了现代人面临的一大挑战。现在&#xff0c;…

网上帮别人开网店卖货的骗局!

小红书帮别人开店卖货的骗局主要涉及到一些不法分子利用小红书平台的流量和用户信任度&#xff0c;通过虚假宣传、承诺高额利润等手段&#xff0c;诱骗用户开店并**所谓的“赚钱机会”。 这些骗局往往以“轻松创业、快速致富”为诱饵&#xff0c;吸引那些对创业充满热情但缺乏经…