初识C++·类和对象(中)(3)

前言,最难的已经结束了,来点轻松了放松一下。

目录

1 流重载

2 const成员

3 取地址及const取地址操作符重载


1 流重载

C语言中printf和scanf是有局限性,只能直接打印内置类型,对于自定义类型就哦豁了,所以在C++中就引用了流的概念,也就是cou cin:

为什么说打印输出的时候不需要占位符,这就是因为流就是一个重载了的函数,所以每次打印的时候都会调用对应的重载函数,比如多次打印的时候,printf一下就打印出来了,但是对于流不行,它要调用许多次重载函数,才能打印出,这也就导致了C++效率不如C语言高,对于不同类型,都可以进行打印,那么我们显式实现一下流重载:

 首先我们要知道cout和cin来源于io流,作为一个全局对象出现的,所以cin的类型是istream,cout是ostream的,所以我们有一个参数的类型一定是ostream,传的参数是cout。

void Date::operator<<(ostream& out);//流重载

声明一下,我们先作为成员函数实现一下:

void Date::operator<<(ostream& out)//流重载
{out << _year << "年" << _month << "月" << _day << "日" << endl;
}

out是形参,用来接收cout,好了,我们实验一下:

	cout << d1;d1.operator<<(cout);

试问哪种形式是正确的?
不墨迹了,第二种是正确的,这与参数的使用顺序有关系,因为是成员函数,所以有一个默认的this指针,但是cout传给了第一个参数,也就是this,d1传给了ostream,这是不是倒反天罡了?
所以:

这样,就拿捏了?
并没有,因为有悖于常态,我们正常使用都是流在前,参数在后,这反过来了还,所以呢,自己控制参数就可以防止反过来的情况:

void operator<<(ostream& out, const Date& d)//流重载
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}

重载为全局函数就ok了,就可以使用cout << d1打印,但是又有问题了,如果我们连续打印呢?
这个其实和连续赋值是一样的,所以我们只需要加上返回值:

ostream& operator<<(ostream& out, const Date& d)//流重载
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}

返回引用是因为原来的运算符重载返回的就是引用,所以我们也返回引用就行。

但是因为我们重载成了全局的,所以要访问就必须把成员变量置为公有的,怎么解决呢?
我们可以使用友元的方法,这里简单提一下,下篇文章介绍:
即我们把这个函数置为友元函数,也就是你是我的朋友,那我就可以用你的东西了:

class Date
{friend ostream& operator<<(ostream& out, const Date& d);
public:
private:int _year;int _month;int _day;
};

在函数名前面加一个friend,你是我的朋友,私有的成员变量你也可以访问了。

cin输入也是一样的,就不做演示了。


2 const成员

先来看这样一段代码:

int main()
{const Date d1(2020, 1, 17);d1.Print();return 0;
}

当d1被const修饰,我们还能调用成员函数吗?这是不可以的,因为const修饰了d1,也就说明d1的权限是const,但是成员函数指针是Date* const this,如果调用函数,就会存在权限放大的问题。

那么祖师爷的解决方法是,散装const来解决:

class Date
{
public:void Print()const;
private:int _year;int _month;int _day;
};
void Date::Print()const
{cout << _year << '-' << _month << '-' << _day << endl;
}

即是函数的后面加一个const,很奇怪对吧,补丁缝缝补补,这个const修饰的是Date* this的*this,加了const参数就变成了const Date* const this,就不存在权限放大的问题,因为const修饰*this的时候,指针指向的元素就不能被修改,所以对于+ -等函数,不修改成员变量的,都可以用const修饰。

那么如果成员函数用了const修饰,但是d1没有被const修饰,调用函数的时候会不会报错呢?

实际上是不会的,因为权限缩小是没有问题的。

所以写函数的时候,只要不是修改成员变量我们把const往上一加是没有问题的。


3 取地址及const取地址操作符重载

这是最后一个成员函数了,是比较简单的,我们看一段代码:

class A
{
public:A* operator&(){cout << "A* operator&" << endl;return this;}const A* operator&()const{cout << "const A* operator&" << endl;return this;}
private:int _a = 1;int _b = 2;int _c = 3;
};
int main()
{A a1;const A aa1;cout << &a1 << endl;cout << &aa1 << endl;return 0;
}

重载&符号其实就是取地址,也就是取自定义类型的地址,但是实际上如果我们不显示调用编译器默认的函数也够用,那么为什么还要单独拎出来呢?
比如返回地址的时候,我想整蛊一下别人呢,比如我返回空,返回假地址,当然平时不用显式定义,默认生成的就够用了。


类和对象中就结束了,终于结束了,挺多的,

感谢阅读!

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

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

相关文章

Linux——(grep指令及zip/tar压缩指令)

1.grep指令 语法&#xff1a; grep【选项】查找字符串 文件 功能&#xff1a; 在文件中搜索字符串&#xff0c;将找到的行打印出来 常用选项&#xff1a; -i &#xff1a;忽略大小写&#xff0c;所以大小写视为相同 -n &#xff1a; 顺便输出行号 -v &#xff1a;反向选择&…

MyBatis 从入门到精通:分页在MyBatis中使用

MyBatis 从入门到精通&#xff1a;分页在MyBatis中使用 先欣赏下美女&#x1f680;分页在MyBatis中使用&#x1f469;‍&#x1f4bb;摘要&#x1f3af;引言&#x1f4a1;正文内容&#x1f615; 为什么要分页&#xff1f;&#x1f680; 使用Limit分页介绍&#x1f4c4; 使用Li…

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器(TcpServer板块)

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff08;TcpServer板块&#xff09; 一、思路图二、模式关系图三、定时器的设计1、Linux本身给我们的定时器2、我们自己实现的定时器&#xff08;1&#xff09;代码部分&#xff08;2&#xff09;思…

Linux华硕笔记本安装ROG Asusctl

基础环境 适用系统&#xff1a; linux mint 21ubuntu 22.04 安装版本&#xff1a; asusctl-5.0.10rust 1.77.2 构建 安装编译环境 sudo apt-get update sudo apt-get install -y \libasound2-dev \libfreetype6-dev \libexpat1-dev \libxcb-composite0-dev \libssl-dev …

数字谐振器设计

数字谐振器设计 电路里的谐振:当电路中激励的频率等于电路的固有频率时&#xff0c;电路电磁振荡的振幅也将达到峰值。 形式一 形式二 例子

4.21java聊天室项目小结

基本完成了用户的登录注册功能&#xff0c;可以实现用户账号登录和邮箱登录功能&#xff0c;忘记密码通过邮箱发送验证码找回&#xff0c;注册账号功能&#xff0c;并传递给客户端更新数据库的表内容 注册功能&#xff1a; 注册成功后密码进行MD5加密并通过服务器保存到数据库…

springboot结合elasticJob

先说一说什么是elasticJob。 ElasticJob是一个分布式任务调度的解决方案&#xff0c;它由俩个相互独立的子项目Elastic-job-lite和Elastic- job-cloud组成。 任务调度&#xff1a;是指系统为了自动完成特定任务&#xff0c;在任务的特定时刻去执行任务的过程。 分布式&#xf…

剑指offer剪绳子;leetcode:LCR 131. 砍竹子 I

现需要将一根长为正整数 bamboo_len 的竹子砍为若干段&#xff0c;每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。 示例 1&#xff1a; 输入: bamboo_len 12 输出: 81提示&#xff1a; 2 < bamboo_len < 58 注意&#xff1a;本题与主站 343 题相同&#…

SQLite导出数据库至sql文件

SQLite是一款实现了自包含、无服务器、零配置、事务性SQL数据库引擎的软件库。SQLite是世界上部署最广泛的SQL数据库引擎。 SQLite 是非常小的&#xff0c;是轻量级的&#xff0c;完全配置时小于 400KiB&#xff0c;省略可选功能配置时小于250KiB。 SQLite 源代码不受版权限制。…

Ubuntu 20.04.06 PCL C++学习记录(二十六)

[TOC]PCL中点云配准模块的学习 学习背景 参考书籍&#xff1a;《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,&#xff0c;PCL版本为1.10.0&#xff0c;CMake版本为3.16&#xff0c;可用点云下载地址 学习内容 在代码中使用ICP迭代最近点算法&#xff0c;程序随机…

2024上海(国际)智慧氧舱暨生物细胞博览会

2024上海(国际)智慧氧舱暨生物细胞博览会 时间 2024年9月21日-23日 地址 上海市浦东新区张江科学会堂 展会亮点 展示国内外医疗器械行业最新发展动态&#xff0c;探讨医疗器械行业发展趋势促进医疗 器械行业健康发展将为全国从事微高压氧舱、医用气调库及其他医用设备、医…

二极管分类及用途

二极管分类及用途 通用开关二极管 特点&#xff1a;电流小&#xff0c;工作频率高 选型依据&#xff1a;正向电流、正向压降、功耗&#xff0c;反向最大电压&#xff0c;反向恢复时间&#xff0c;封装等 类型&#xff1a;BAS316 ; IN4148WS 应用电路: 说明&#xff1a;应用…

【Linux】引导过程与服务控制

目录 一、Linux操作系统引导过程 1.linux开机引导过程 2.系统初始化进程 1.init进程 2.进程启动方式 二、运行级别和Systemd单元类型 1.运行级别 2.Systemd 三、启动类故障恢复 1.修复MBR扇区故障 2.修复GRUB引导故障 3.root密码忘记的修改方式 四、系统服务控制 …

MATLAB求和函数

语法 S sum(A) S sum(A,“all”) S sum(A,dim) S sum(A,vecdim) S sum(,outtype) S sum(,nanflag) 说明 示例 S sum(A) 返回沿大小大于 1 的第一个数组维度计算的元素之和。 如果 A 是向量&#xff0c;则 sum(A) 返回元素之和。 如果 A 是矩阵&#xff0c;则 sum(A) 将…

配置静态路由实现全网互通

1、实验环境 如图下所示&#xff0c;三台路由器R1&#xff0e;R2&#xff0c;R3两两互连&#xff0c;每台路由器上都配置了Loopback地址模拟网络环境。 2、需求描述 需要在三台路由器上配置静态路由&#xff0c;以实现各网段之间的互通。 若要实现全网互通,必须明确如下两个问…

UI5 快速入门教程

环境准备 node >16.8 ,VSCode&#xff0c;官方网址 开始 创建一个根文件夹&#xff0c;根文件中创建一个package.json文件 {"name": "quickstart-tutorial","private": true,"version": "1.0.0","author":…

【JavaWeb】Day51.Mybatis动态SQL

什么是动态SQL 在页面原型中&#xff0c;列表上方的条件是动态的&#xff0c;是可以不传递的&#xff0c;也可以只传递其中的1个或者2个或者全部。 而在我们刚才编写的SQL语句中&#xff0c;我们会看到&#xff0c;我们将三个条件直接写死了。 如果页面只传递了参数姓名name 字…

flutter 实现表单的封装包含下拉框和输入框

一、表单封装组件实现效果 //表单组件 Widget buildFormWidget(List<InputModel> formList,{required GlobalKey<FormState> formKey}) {return Form(key: formKey,child: Column(children: formList.map((item) {return Column(crossAxisAlignment: CrossAxisAlig…

java优先级队列(堆)详解

一、优先级概念 什么是优先级&#xff1a;比如女士优先&#xff0c;个子低的优先排到前面去&#xff0c;有一部分数据具备优先级&#xff0c;要以优先级的顺序将顺序存储起来。 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#…

Java:String类

目录 1.String类的重要性2.String对象的比较2.1 比较是否引用同一个对象2.2 boolean equals(Object anObject) 方法&#xff1a;按照字典序比较2.3int compareTo(String s)方法: 按照字典序进行比较2.4 boolean equalsIgnoreCase(Object anObject)方法&#xff1a;忽略大小写的…