【C++】-const对象及成员函数之类和对象中篇完结(中)

💖作者:小树苗渴望变成参天大树
❤️‍🩹作者宣言:认真写好每一篇博客
💨作者gitee:gitee
💞作者专栏:C语言,数据结构初阶,Linux,C++

文章目录

  • 前言
  • 一、案例的引入
  • 二、const对象和成员函数
  • 三、取地址及const取地址操作符重载
  • 四、总结


前言

今天我们来讲讲const对成员对象和成员函数都有那些要注意的细节,还有两个默认成员函数的简单讲解,内容不是特别难,对于const大家要熟悉引用中对于权限的放大,缩小,平移的理解,可以参考这篇引用的第6.5节讲的内容,再来理解这个就好理解一点,那我们开始进入正文的讲解


一、案例的引入

我们其实已经接触过了一点关于const修饰对象的案例了,再讲解输入输出运算符重载的博客中,全局的重载函数访问私有的成员有两种方法,一个使用友元,一个使用共有的成员函数将值返回出来,第二种方法

在这里插入图片描述
我们当时说为什么这个不加const修饰,主要原因是类型的不匹配,对于我们成员函数,我们再类和对象的第一篇博客就讲解到过,每个正常成员函数都有一个隐藏的this指针(有的用static修饰的成员函数就没有this指针,所以这里说正常的成员函数),对于隐藏的this指针他的类型为类名+*+this(以日期类为例:date * this),准确来说,他的类型为(*date const this)修饰的this本身不变修改,当时没说明是怕大家不理解,这里再提出来,对于上图的案例,其实应该写成这样的:
在这里插入图片描述
通过这个图,大家应该差不多明白了为什么上面不加const了吧,大家有了这方面的了解之后,我们再来细看

二、const对象和成员函数

再上面我们如果想传const的对象应该怎么办,this指针本身就是隐藏的,所以没有办法显示的加const,那么祖师爷针对这个问题就规定了再括号后面加一个const,例如:

class Date
{
public:
	Date(int year=1, int month=1, int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "Print()" << endl;
	}
	void Print() const
	{
		cout << "Print()const" << endl;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};

我们来测试一下:
在这里插入图片描述
我们来看看加const的成员函数能不能调用普通对象:
在这里插入图片描述

因为从Datethis传给const Datethis是权限的缩小,所以可以,反过来就不行,既然这样有的人就像把全部的成员函数都加一个const这样不是更好吗??其实并不是,对于那些不修改对象的成员函数可以加,效果更好,修改自身不可以加

在这里插入图片描述

这个const对象d2无法调用非const的成员函数,原因就是权限的放大了,const对象没有办法传给非const的this

通过上面的案例

  1. const对象不可以调用非const成员函数
  2. 非const对象可以调用const成员函数 **

我们来看看之前写了日期类那些可以加:

class date 
{
public:
	date(int year = 1, int month = 1, int day = 1)//全缺省的构造函数
	{
		if (day > 0 && day <= getmonthday(year, month) && month > 0 && month < 13)
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "非法初始化" << endl;
			assert(false);
		}
	}
	//拷贝构造
	//赋值重载
	//析构函数

	void print()const//当成内联函数
	{
		cout << _year << " " << _month << " " << _day << endl;
	}
	bool operator<(const date& d)const;
	bool operator==(const date& d)const;
	bool operator>(const date& d)const;
	bool operator>=(const date& d)const;
	bool operator<=(const date& d)const;
	bool operator!=(const date& d)const;

	date& operator+=(int day);
	date operator+(int day)const;


	static int getmonthday(int year, int month);

	// 日期-天数
	date operator-(int day)const;
	// 日期-=天数
	date& operator-=(int day);

	// 前置++
	date & operator++();
	// 后置++
	date operator++(int);
	// 后置--
	date operator--(int);
	// 前置--
	date& operator--();

	int operator-(const date& d)const;
	int getyear()const
	{
		return _year;
	}
	int getmonth()const
	{
		return _month;
	}
	int getday()const
	{
		return _day;
	}
	friend ostream& operator<<(ostream& cout, const date& d);
	friend istream& operator>>(istream& cin, date& d);

再定义的地方也要加const

不加会出现那些情况:
在这里插入图片描述
大家看这样就比较不了,原因是小于里面的隐藏this不是const修饰类型,而运算符的第一个参数默认传给this的,第二不行的原因是,d2是const修饰类型,传给的this是普通的类型,是权限的放大,所以不行
在这里插入图片描述
所以必须要在小于那里加const:
在这里插入图片描述
所以有的时候不加还是不行的,根据具体实际来写

  1. 要修改成员变量的函数不能加
  2. 只要成员函数内部不修改成员变量都应该加const,这样const对象和普通对象都可以调用

其实对于单个函数需不需要使用const很好判断的,但是对于函数复用,就很麻烦,我们来看看下面两个问题:(这样自己再理解一下日期类那些函数加const的特性)

  1. const成员函数内可以调用其它的非const成员函数吗?
    在这里插入图片描述

  2. 非const成员函数内可以调用其它的const成员函数吗?
    在这里插入图片描述
    大家应该看到想要的结果了吧,在日期类中,我们的小于和等于是自己实现的,其余的都是复用这两个函数,如果这两个不加const,其余的都不能加,加了就会报错。

在这里插入图片描述
只要复用了小于和等于的函数都需要加const,不然就会报错,所以大家在写日期类的时候要主要了,如果有的函数用的时候保存,大概路是类型传参不匹配,往前面检查就行了。这个在后面也会遇到的,现在大家理解起来还是有点困难的。

三、取地址及const取地址操作符重载

我们在类和对象中篇的时候,讲过我们有六个默认成员函数,之前已经讲过了四个,现在还剩两个,这两个几乎很少需要自己实现,默认生成的就可以完成需求,这两个没啥可以讲的,就是取到对象的地址

class Date
{ 
public :
 Date* operator&()
 {
   return this ;
 }
 const Date* operator&()const
 {
 return this ;
 }
private :
 int _year ; // 年
 int _month ; // 月
 int _day ; // 日
};

在这里插入图片描述
const的取地址运算符就是为了取出const对象的地址,这里面有一个注意的细节,我们的d2对象是const修饰的,所以必须初始化,因为只有一次初始化的机会。我这里直接给缺省值,调用构造函数就行了。

自己手写这个函数,可能不想让别人得到对象的地址,返回一个假的数据给他:
在这里插入图片描述
大家知道了解就好,以后开发几乎不咋需要自己实现

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!

四、总结

到这里我们的类和对象中篇算是讲解完了,里面的内容非常的多,尤其是细节方面的,大家一定要理解,画图,接下来我将讲解类和对象下篇的知识点,初始化列表是一个比较难的知识点,大家做好准备,我们下篇再见。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HR怎么看待PMP证书呢?

我们可以先了解一下各个公司对于PMP证书的一个观点 针对PMP证书&#xff0c;在HR看来&#xff0c;有这几个直观的感受和判断&#xff1a; 公司要求PMP优先&#xff0c;那我盯着这个看就行&#xff0c;没有就不要&#xff0c;省事儿招的多了也有一些基本了解&#xff0c;考到这…

从C语言到C++⑨(第三章_CC++内存管理)详解new和delete+面试题笔试题

目录 1. C语言动态内存管理 1.1 C/C内存分布 1.2 C语言中动态内存管理的方式 2. C动态内存管理方式 2.1 new/delete操作内置类型 2.2 初始化new数组的问题 2.3 new 和 delete 操作自定义类型 3. operator new与operator delete函数详解 3.1 operator new与operator de…

计算机专业含金量高的证书

目录 第一种证书&#xff1a;计算机技术与软件专业资格考试证书 第二种证书&#xff1a;微软认证 第三种证书&#xff1a;Oracle认证 第四种证书&#xff1a;思科认证 第五种证书&#xff1a;华为认证 第六种证书&#xff1a;红帽认证工程师 第七种证书&#xff1a;阿里…

数据表的创建和管理 (数据库)

目录 一、数据表结构的创建 1、利用create命令创建表 2&#xff0e;关于创建表时运用约束的说明 &#xff08;1&#xff09;空值约束&#xff08;NULL or NOT NULL&#xff09; &#xff08;2&#xff09;主键约束&#xff08;primary key constraint&#xff09; &#x…

Java多线程入门到精通学习大全?了解线程池和线程常用集合的基本原理、代码示例!(第六篇:线程池和集合的学习)

设计和实现多线程应用程序需要了解线程池、线程常用集合等相关知识。下面我们将分别介绍线程池、线程常用集合的原理、使用场景、代码示例、注意事项和总结。 1. 线程池 线程池是一种线程调度机制&#xff0c;它可以管理多个线程&#xff0c;并且可以重复使用这些线程来处理多…

Node.js 与 TypeScript

目录 1、什么是 TypeScript 2、运行TypeScript 3、TypeScript 在Node.js 生态中的情况 1、什么是 TypeScript TypeScript是一种流行的开源语言&#xff0c;由微软维护和开发。它受到了世界各地许多软件开发人员的喜爱和使用。 基本上&#xff0c;它是JavaScript的超集&…

SpringBoot+@Validate+全局异常拦截实现自定义规则参数校验(校验get请求参数不能为空且在指定枚举类型中)

场景 SpringBootValidated实现参数验证(非空、类型、范围、格式等)-若依前后端导入Excel数据并校验为例&#xff1a; SpringBootValidated实现参数验证(非空、类型、范围、格式等)-若依前后端导入Excel数据并校验为例_validated 怎么设置boolean类型非空_霸道流氓气质的博客-…

公司新来的00后真是卷王,工作没两年,跳槽到我们公司起薪18K都快接近我了

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。…

瑞云渲染农场怎么用,瑞云渲染多少钱一分钟?

Renderbus瑞云渲染农场作为亚洲前沿的 云渲染平台&#xff0c;一直以“做最好的云渲染工具”为愿景&#xff0c;紧跟CG行业的技术创新与发展&#xff0c;致力于提供专业可靠、安全稳定、可持续创新的云渲染解决方案&#xff0c;助力推动行业快速发展&#xff0c;被誉为中国云渲…

【2023/05/10】Mitchel Resnick

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第5天。 Share Her wistful face haunts my dreams like the rain at night. 译文&#xff1a; 她的热切的脸&#xff0c;如夜雨似的&#xff0c;搅扰着我的梦魂。 Once we dreamt that we were stra…

支付系统设计三:渠道网关设计06-业务处理

文章目录 前言一、业务服务工厂二、业务处理服务1. 业务处理服务2. 业务处理抽象服务3. 流量控制4. 报文提交4.1 获取交易的服务端通讯列表4.2 循环请求支付渠道4.2.1 报文组装4.2.2 报文发送4.2.2.1 协议处理器获取4.2.2.2 构建通讯客户端4.2.2.3 发送请求4.2.2.4 响应报文读取…

股票量价关系基础知识2

内盘与外盘 外盘&#xff0c;是指在一个交易日获某段交易时间内&#xff0c;买方主动提价以委卖价成交的股数之和&#xff0c;也称为主动性买盘 内盘&#xff0c;是指在一个交易日获某段交易时间内&#xff0c;卖方主动降价以委买价成交的股数之和&#xff0c;也称主动性卖盘。…

中文润色ai-ai原创文章生成器

在现代社会&#xff0c;每天都有大量的中文文章被发布到互联网上&#xff0c;这些文章的质量和可读性直接影响着读者的阅读体验和文章的传播效果。为了让文章更加美好&#xff0c;越来越多的人开始尝试使用中文润色ai技术。 中文润色ai是一种先进的人工智能技术&#xff0c;它能…

数字图像处理-matlab图像内插

matlab图像内插 最近邻插值双线性插值双三次插值总结 最近邻插值 目标各像素点的灰度值代替源图像中与其最邻近像素的灰度值 参考博客 假设一个2X2像素的图片采用最近邻插值法需要放大到4X4像素的图片&#xff0c;右边该为多少&#xff1f; 最近邻插值法坐标变换计算公式&…

Vue核心 列表渲染 数据监视

1.13.列表渲染 1.13.1.基本列表 v-for指令 用于展示列表数据语法&#xff1a;&#xff0c;这里key可以是index&#xff0c;更好的是遍历对象的唯一标识可遍历&#xff1a;数组、对象、字符串&#xff08;用的少&#xff09;、指定次数&#xff08;用的少&#xff09; <!…

Kubesphere流水线实现蓝绿发布

Kubesphere流水线实现蓝绿发布 1. Gitlab仓库准备 1.1 创建仓库 新建空白项目,名字随便取 greenweb复制克隆地址 http://192.168.31.199/deploy/greenweb.git1.2 初始化并上传代码 克隆并初始化代码仓库 mkdir git cd git git clone http://192.168.31.199/deploy/green…

【嵌入式烧录刷写文件】-2.3-删除/修改Intel Hex文件中指定地址范围内的数据

案例背景&#xff08;共6页精讲&#xff09;&#xff1a; 有如下一段HEX文件&#xff0c;如何“自动”地完成地址范围0x9110-0x9113数据的删除或修改。 :2091000058595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576775F :2091200078797A7B7C7D7E7F808182838485…

一觉醒来Chat gpt就被淘汰了

目录 什么是Auto GPT&#xff1f; 与其他语言生成模型相比&#xff0c;Auto GPT具有以下优点 Auto GPT的能力 Auto GPT的能力非常强大&#xff0c;它可以应用于各种文本生成场景&#xff0c;包括但不限于以下几个方面 Auto GPT的历史 马斯克说&#xff1a;“ChatGPT 好得吓…

记csdn打不开或打开缓慢后的修复--如何查找dns并修改hosts文件

记csdn打开缓慢后的修复–如何查找dns并修改hosts文件 问题&#xff1a; CSDN文章打开的十分缓慢&#xff0c;经常出现无法打开页面的错误提示 &#xff08;以前用的好好的&#xff0c;现在不知道公司局域网改了什么东西&#xff0c;导致我的电脑打开CSDN经常缓慢好久&#x…

Lesson14 高级IO

前言 IO 等待 数据拷贝,比如read/recv,write/send只要在单位事件里,让等的比重减低,IO的效率就越高 五种IO模型 钓鱼小案例 阻塞式 阻塞式: 张三拿着一根鱼竿,一直在岸边钓鱼,期间一直盯着鱼竿,等待鱼上钩 非阻塞式轮询式 非阻塞式轮询式: 李四拿着一根鱼竿,在岸边钓鱼,期…