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

news2024/9/29 9:30:18

Ⅰ. 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);      //普通对象d1
    d1.Print();
​
    const Date d2(2077,1,1);  //被const修饰的对象d2
    d2.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.coloradmin.cn/o/933513.html

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

相关文章

使用 Transformer 和 Amazon OpenSearch Service 构建基于列的语义搜索引擎

在数据湖中&#xff0c;对于数据清理和注释、架构匹配、数据发现和跨多个数据来源进行分析等许多操作&#xff0c;查找相似的列有着重要的应用。如果不能从多个不同的来源准确查找和分析数据&#xff0c;就会严重拉低效率&#xff0c;不论是数据科学家、医学研究人员、学者&…

机器学习:无监督学习

文章目录 线性学习方法聚类ClusteringKmeansHAC 分布表示降维PCAMatrix FactorizationManifold LearningLLELaplacian Eigenmapst-SEN 线性学习方法 聚类Clustering Kmeans 随机选取K个中心&#xff0c;然后计算每个点与中心的距离&#xff0c;找最近的&#xff0c;然后更新中…

计算机竞赛 基于大数据的社交平台数据爬虫舆情分析可视化系统

文章目录 0 前言1 课题背景2 实现效果**实现功能****可视化统计****web模块界面展示**3 LDA模型 4 情感分析方法**预处理**特征提取特征选择分类器选择实验 5 部分核心代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据…

WOFOST模型与PCSE模型应用

实现作物产量的准确估算对于农田生态系统响应全球变化、可持续发展、科学粮食政策制定、粮食安全维护都至关重要。传统的经验模型、光能利用率模型等估产模型原理简单&#xff0c;数据容易获取&#xff0c;但是作物生长发育非常复杂&#xff0c;中间涉及众多生理生化过程&#…

MySQL - 安装

MySQL 安装 | 菜鸟教程 linux:yum方式安装mysql 8 - 点击领取 一、Cent OS系统 &#xff08;一&#xff09;安装前 1.1 删除mariadb数据库软件包 rpm -qa|grep mari //查询mariadb数据库软件包 rpm -e --nodeps 查到的包名 //删除软件包 2.1 检…

职业发展和认证指导:提供网络安全从业者的职业规划建议,介绍各类认证考试和培训资源

章节一&#xff1a;引言 网络安全在今天的数字化世界中变得愈发重要&#xff0c;随之而来的是对网络安全专业人才的持续需求。作为一个追求在网络安全领域取得成功的从业者&#xff0c;职业规划和持续学习是不可或缺的一部分。本文将为你详细介绍如何规划你的网络安全职业发展…

04.sqlite3学习——DDL(数据定义:创建和删除表)

目录 DDL&#xff08;数据定义&#xff1a;创建和删除表&#xff09; SQLite 创建表 语法 实例 字段修饰符 primary key 定义主键列 AUTOINCREMENT 自动增长 UNIQUE 字段的值唯一 NOT NULL 字段的值不为空 SQLite 修改表 增加字段add 修改表名rename to SQLite 删…

MySQL—buffer pool

一、buffer pool的介绍 Buffer pool是什么 一个内存区域&#xff0c;为了提⾼数据库的性能&#xff0c;数据库操作数据的时候&#xff0c;把硬盘上的数据加载到buffer pool&#xff0c;不直接和硬盘打交道&#xff0c;操作的是 buffer pool的数据&#xff0c;数据库的增删改查…

指针C语言

1指针方式 1.int a,*p&a; 2. int a;int *p&a;特点&#xff1a; 1.指针变量与类型无关&#xff0c;在TC占2字节&#xff0c;在VC下占四字节 2.指针变量的引用 1.直接引用 2.间接引用 注意*的运算对象必须为地址 *p1; //相当于取p指针指向的值然后&#xff0b;1 int …

同源策略以及SpringBoot的常见跨域配置

先说明一个坑。在跨域的情况下&#xff0c;浏览器针对复杂请求&#xff0c;会发起预检OPTIONS请求。如果服务端对OPTIONS进行拦截&#xff0c;并返回非200的http状态码。浏览器一律提示为cors error。 一、了解跨域 1.1 同源策略 浏览器的同源策略&#xff08;Same-Origin Po…

SpringBoot入门篇2 - 配置文件格式、多环境开发、配置文件分类

目录 1.配置文件格式&#xff08;3种&#xff09; 例&#xff1a;修改服务器端口。&#xff08;3种&#xff09; src/main/resources/application.properties server.port80 src/main/resources/application.yml&#xff08;主要用这种&#xff09; server:port: 80 src/m…

小程序input的placeholder不垂直居中的问题解决

input的placeholder不垂直居中&#xff0c;input设置高度后&#xff0c;使用line-height只能使输入的文字垂直居中&#xff0c;但是placeholder不会居中&#xff0c;反而会偏上。 首先placeholder样式自定义 有两种方法&#xff0c;第一种行内样式&#xff1a; <input ty…

全国首台!浙江机器人产业集团发布垂起固定翼无人机-机器人自动换电机巢

展示突破性创新技术&#xff0c;共话行业发展趋势。8月25日&#xff0c;全国首台垂起固定翼无人机-机器人自动换电机巢新品发布会暨“科创中国宁波”无人机产业趋势分享会在余姚市机器人小镇成功举行。 本次活动在宁波市科学技术协会、余姚市科学技术协会指导下&#xff0c;由浙…

squid服务器

目录 squid初识 安装squid代理 常用命令 主要配置文件 正向代理 环境配置 linux服务器设置 windows客户端设置 反向代理 环境配置 在web服务器配置服务 linux服务器配置 squid初识 含义&#xff1a;squid cache是一个流行的自由软件&#xff08;GNU通用公共许可证…

奥比中光:进击具身智能,打造机器人之眼

大数据产业创新服务媒体 ——聚焦数据 改变商业 跨过奇点的生成式人工智能是一个缸中大脑&#xff0c;只有赋予形体&#xff0c;才能与物理世界产生互动。 在5月的ITF世界半导体大会上&#xff0c;英伟达创世人兼CEO黄仁勋说&#xff0c;人工智能的下一波浪潮将是具身智能。 8…

消息中间件 介绍

MQ简介 MQ,Message queue,消息队列&#xff0c;就是指保存消息的一个容器。具体的定义这里就不类似于数据库、缓存等&#xff0c;用来保存数据的。当然&#xff0c;与数据库、缓存等产品比较&#xff0c;也有自己一些特点&#xff0c;具体的特点后文会做详细的介绍。 现在常用…

TabBar组件如何跳转页面?

1、先引入 2、假数据 const tabs [{key: home,title: 首页,icon: <AppOutline />,badge: Badge.dot,},{key: todo,title: 待办,icon: <UnorderedListOutline />,badge: 5,},{key: message,title: 消息,icon: (active: boolean) >active ? <MessageFill /&…

开源与数据科学:一个完美的组合?

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

如何在VSCode中将html文件打开到浏览器

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Java学数据结构(2)——树Tree 二叉树binary tree 二叉查找树 AVL树 树的遍历

目录 引出什么是树Tree&#xff1f;树的实现二叉树binary tree查找树ADT——二叉查找树Binary Search Tree1.contains方法2.findMax和findMin方法3.insert方法4.remove方法&#xff08;复杂&#xff09;二叉查找树的深度 AVL(Adelson-Velskii和Landis)树——平衡条件(balance c…