【C++】const成员 | 取地址运算符重载

Ⅰ. const成员

两种const

我们知道,用const修饰 能起到保护,使之不被修改的作用。

修饰指针的const有两种位置:

我们学过的this指针,就被后者所修饰,因此无法被修改。

const成员函数

➡️为了保护函数里的成员,使不被修改,C++引入了const成员函数。

“const成员函数” ,就是被const修饰的成员函数。

const的存在,使我们不能对任何成员进行修改。

➡️它长这样:

void Date::Print() const
{……
}

这个函数相当于:

void Date::Print(const Date* const this)
{……
}

❗注意:前后两个const的意义是不一样的。

前者修饰*this,保护 this指向的空间的内容 不被修改。

后者修饰this,保护this指针不被修改。

❓🤔这个const的位置好怪啊,为啥要放在最末尾?而不是开头?

const:爷就长得怪,咋地!

不能放开头啊,那样const就成修饰返回值的了。

➡️对比this指针的类型:

普通函数:类型* const

const成员函数:const 类型* const

➡️权限问题:

就像公司上下级关系,权限大的可以调用权限小的;

而权限小的不可以调用权限大的。

解释这张图:

被const修饰的Print() / d2,因为被限制了内容不能修改,所以权限相对更低。

未被const修饰的Print() / d1,可被修改,自由度更高,权限相对更高。

彼此的关系就用上下级、平级的关系来理解。

所以,const成员函数内部 不可调用 其他非const成员函数;

而非const……可调用……const……。

➡️什么时候加const?

如果一个函数不用修改,性质是只读的,那就加上const来保护。

如果其性质是可读可写,那就不能加。

Ⅱ. 取地址运算符重载

先亮身份:类的六大默认成员函数之一。

函数名:operator&

作用:自定义类型的取地址

引入

来看这个例子。我们知道,自定义类型的运算 需要我们自己去实现 运算符重载,运算符&同样如此。

而这里,我们没写operator&,那究竟能否取地址成功呢?

class Date {
public:Date(int year = 1900, int month = 1, int day = 1) {_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
​
int main() {
​Date d1(2000, 1, 1);cout << &d1 << endl;   //前面没写operator&//能否取地址成功呢?return 0;
}

结果:

 

取地址成功!

❓But why?

💡这是因为,C++很贴心地将 取地址运算符重载 纳入默认成员函数。

也就是说,operator& 和前几位默认成员函数的福利一样:

如果我们写了,编译器会自动调用;

如果没写,编译器会自动生成,并自动调用。

❓取地址运算符重载长啥样?

Here comes the model:

Date* operator&()
{return this;
}

取地址运算符重载分两种:

1.& 普通对象

2.& const修饰的对象

普通对象取地址

很easy,不详讲了。我们来手动实现一下:

class Date {
public:Date(int year = 1900, int month = 1, int day = 1) {_year = year;_month = month;_day = day;}
​Date* operator&() {return this;    //this就是它的地址}
​
private:int _year;int _month;int _day;
};
​
int main() {Date d1(2000, 1, 1);cout << &d1 << endl;
​return 0;
}

const对象取地址

当对象被const修饰时,会特殊一些。

来看d1和d2的对比:

class Date {
public:Date(int year = 1900, int month = 1, int day = 1) {_year = year;_month = month;_day = day;}void Print(){printf("%d-%d-%d\n", this->_year, this->_month, this->_day);}
​
private:int _year;int _month;int _day;
};
​
int main() {Date d1(2000, 1, 1);      //普通对象d1d1.Print();
​const Date d2(2077,1,1);  //被const修饰的对象d2d2.Print();
​return 0;
}

然而,压根编译不过去:

普通对象d1没问题,而const修饰的d2却亮红牌了,为啥?

其实,const成员报错的原因往往是🤔……权限的放大!

来分析下:

Print函数中,this指针的类型是:Date* const

而d2的类型是:const Date* const

所以说,d2去调用Print(),是一次权限的放大!是以下犯上,大逆不道!

💡对此,解决方案是:

const修饰的对象,应调用const取地址运算符重载

即,d2应调用:

void  Print() const{printf("%d-%d-%d\n", this->_year, this->_month, this->_day);
}

什么时候要手动实现operator& ?

我们尽可放宽心,即使是const对象,编译器仍会自动生成 相应的const operator&。

所以无论是 普通对象 还是 const对象 取地址,我们都无需手动实现operator&。

大部分情况下,取地址运算符重载都不用自己写,编译器默认生成的就够用了。

只有特殊情况才需要重载,

如:你不希望别人取到你的地址。那这时就:

Date* operator&(){return nullptr;
}

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

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

相关文章

《Java极简设计模式》第05章:原型模式(Prototype)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 源码地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

Elasticsearch 8.X reindex 源码剖析及提速指南

1、reindex 源码在线地址 为方便大家验证&#xff0c;这里给出 reindex github 源码地址。 https://github.com/elastic/elasticsearch/blob/001fcfb931454d760dbccff9f4d1b8d113f8708c/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java reindex 常见…

开源软件的崛起:历史与未来

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Lambda函数

一.概念 1.利用lambda表达式可以编写内嵌的匿名函数&#xff0c;用以替换独立函数或者函数对象 2.每当你定义一个lambda表达式后&#xff0c;编译器会自动生成一个匿名类&#xff08;这个类当前重载了&#xff08;&#xff09;运算符&#xff09;&#xff0c;我们称为闭包类型…

Lazada商品详情接口 获取Lazada商品详情数据 Lazada商品价格接

一、引言 随着电子商务的迅速发展和普及&#xff0c;电商平台之间的竞争也日趋激烈。为了提供更好的用户体验和更高效的后端管理&#xff0c;Lazada作为东南亚最大的电商平台之一&#xff0c;开发了一种商品详情接口&#xff08;Product Detail API&#xff09;。该接口允许第…

根据源码,模拟实现 RabbitMQ - 转发规则实现(6)

目录 一、转发规则实现 1.1、需求分析 1.2、实现 Router 转发规则 1.2.1、bindingKey 和 routingKey 参数校验 1.2.2、消息匹配规则 1.2.3、主题交换机匹配规则 一、转发规则实现 1.1、需求分析 这里主要实现 routingKey 和 bindingKey 参数的校验&#xff0c;以及 Topic…

Python(.pyc)反编译:pycdc工具安装与使用

本文将介绍如何将python的.pyc文件反编译成源码&#xff0c;以便我们对源码的学习与改进。pycdc工具安装 下载地址&#xff1a; 1、Github地址&#xff1a;https://github.com/zrax/pycdc &#xff0c;下载后需要使用CMake进行编译。 2、已下载好及编译好的地址&#xff1a;ht…

ISIS路由协议

骨干区域与非骨干区域 凡是由级别2组建起来的邻居形成骨干区域&#xff1b;级别1就在非骨干区域&#xff0c;骨干区域有且只有一个&#xff0c;并且需要连续&#xff0c;ISIS在IP环境下目前不支持虚链路。 路由器级别 L1路由器只能建立L1的邻居&#xff1b;L2路由器只能建立L…

1.2 Kali Linux的网络配置

前言 最新文章请见此处&#xff0c;持续更新&#xff0c;敬请订阅&#xff01;https://blog.csdn.net/algorithmyyds/category_12418682.html 网络在如今的社会已是十分重要的媒介&#xff0c;如果没有网络&#xff0c;很多事情将难以办成。渗透测试也是一样——毕竟在攻击机…

学习设计模式之享元模式,但是宝可梦

前言 作者在准备秋招中&#xff0c;学习设计模式&#xff0c;做点小笔记&#xff0c;用宝可梦为场景举例&#xff0c;有错误欢迎指出。 享元模式 1 介绍 享元模式很好理解&#xff0c;它主要是为了减少创建对象的数量&#xff0c;属于结构型设计模式 目的&#xff1a;减少…

Jacoco XML 解析

1 XML解析器对比 1. DOM解析器&#xff1a; ○ 优点&#xff1a;易于使用&#xff0c;提供完整的文档树&#xff0c;可以方便地修改和遍历XML文档。 ○ 缺点&#xff1a;对大型文档消耗内存较多&#xff0c;加载整个文档可能会变慢。 ○ 适用场景&#xff1a;适合小型XML文档…

函数式编程-Stream流学习第二节-中间操作

1 Stream流概述 java8使用的是函数式编程模式,如同它的名字一样&#xff0c;它可以用来对集合或者数组进行链状流式操作&#xff0c;让我们更方便的对集合或者数组进行操作。 2 案例准备工作 我们首先创建2个类一个作家类&#xff0c;一个图书类 package com.stream.model;…

03.sqlite3学习——数据类型

目录 sqlite3学习——数据类型 SQL语句的功能 SQL语法 SQL命令 SQL数据类型 数字类型 整型 浮点型 定点型decimal 浮点型 VS decimal 日期类型 字符串类型 CHAR和VARCHAR BLOB和TEXT SQLite 数据类型 SQLite 存储类 SQLite 亲和类型(Affinity)及类型名称 Boo…

opencv案例03 -基于OpenCV实现二维码生成,发现,定位,识别

1.二维码的生成 废话不多说&#xff0c;直接上代码 # 生成二维码 import qrcode# 二维码包含的示例数据 data "B0018" # 生成的二维码图片名称 filename "qrcode.png" # 生成二维码 img qrcode.make(data) # 保存成图片输出 img.save(filename)img.sh…

vue关闭弹窗刷新父页面 this.$refs

代码截图 主页面 弹出框页面 接这一篇文章后续 参考链接

Python 数据分析——matplotlib 快速绘图

matplotlib采用面向对象的技术来实现&#xff0c;因此组成图表的各个元素都是对象&#xff0c;在编写较大的应用程序时通过面向对象的方式使用matplotlib将更加有效。但是使用这种面向对象的调用接口进行绘图比较烦琐&#xff0c;因此matplotlib还提供了快速绘图的pyplot模块。…

Python迭代器和生成器

一、迭代器 1.1、什么是迭代 迭代是指反复的执行一个过程&#xff0c;每次执行都会根据前一次的结果进行调整和优化。在计算机编程中&#xff0c;迭代常常用于循环执行某个操作&#xff0c;直到达到特定的条件或达成目标。迭代也可以用于指代软件开发中的“迭代开发”&#x…

R语言主成分分析

R语言主成分分析 之前介绍过怎么用SPSS进行主成分分析(PCA)&#xff0c;已经忘了的朋友们可以到主页看看 今天主要介绍下R语言主成分分析的几种方法。都是入门级别&#xff0c;跟着我一步步走&#xff0c;一点都不难哈~ 首先调用R语言自带的数据集&#xff0c;USArrests。这…

【Go 基础篇】Go语言中的数组:初识与应用

Go语言以其简洁、高效和强大的特性在编程界广受欢迎。数组作为一种基本的数据结构&#xff0c;在各种应用场景中扮演着重要角色。本文将引入Go语言中的数组&#xff0c;介绍其特点、创建、初始化以及基本应用&#xff0c;为你打开数组的大门。 前言 数组是一种固定大小的数据…

七层、四层和五层网络模型区别和联系

七层、四层和五层网络模型区别和联系 概述OSI网络7层模型&#xff08;概念型框架&#xff09;概述图片分析 四层模型概述常用协议OSI与TCP/IP四层的区别 五层模型概述三种网络模型对比 总结 概述 网络模型-七层模型&#xff08;OSI模型&#xff09;、五层协议体系结构和TCP/IP…