初识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.hqwc.cn/news/638065.html

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

相关文章

基础SQL DDL语句

MySQL的DDL&#xff08;Data Definition Language&#xff09;语句用于定义或修改数据库结构。 DDL数据库操作 查看所有的数据库 show databases; 红色圈起来的是系统数据库&#xff0c;是系统自带的 mysql&#xff1a;包含存储MySQL服务器运行时所需信息的表。这包括数据字典…

【Linux】小知识点温习---命令

许多常见命令会用&#xff0c;但是很少注意他们的区别&#xff1b;亦或在学习中使用较少&#xff0c;容易忘记&#xff0c;今天做一个回顾。 ls系列 -a:显示所有文件&#xff08;包括隐藏文件&#xff09; -l:将文件以竖列形式显示 -i&#xff1a;显示文件的inode编号 pwd 显…

Redis数据类型——String

Redis官网指令文档&#xff1a;Commands | Docs 前言 此处的String类型是针对Redis的Value的&#xff0c;因为Key的形式都是String&#xff0c;而Value则有哈性、列表、集合等形式。 众所周知&#xff0c;由于不同编码&#xff0c;经常会出现乱码的问题&#xff0c;但在Redi…

Umi.js:登录之后需要手动刷新权限菜单才能渲染

在使用Umi.js开发后台管理页面时&#xff0c;用户登录之后&#xff0c;总是需要手动刷新一次页面&#xff0c;才能够拿到全局状态/权限信息。 问题描述 结合使用umi/plugin-layout和umi/plugin-access&#xff0c;登录进入页面&#xff0c;配置的权限菜单未渲染&#xff0c;需…

Redis中的慢查询日志(一)

慢查询日志 概述 Redis的慢查询日志功能用于记录执行时间超过给定时长的命令请求&#xff0c;用户可以通过这个功能产生的日志来 监视和优化查询速度。服务器配置有两个和慢查询日志相关的选项: 1.slowlog-log-slower-than选项指定执行时间超过多少微妙(1秒1000 000微妙)的命…

一二三应用开发平台使用手册——系统管理-用户组-使用说明

概述 在RBAC模型中&#xff0c;资源、角色、用户三个关键元素&#xff0c;构成权限体系。在平台设计和实现的时候&#xff0c;以下几个核心问题思考如下&#xff1a; 角色&#xff0c;单层平铺还是树形结构&#xff1f; 在小型应用中&#xff0c;角色数量有限的情况下&#x…

VisionPro 脚本教程专栏:深入理解与实践

文章目录 VisionPro 脚本教程专栏&#xff1a;深入理解与实践。目录1. 脚本简介1.1 VisionPro 项目组成1.2 脚本的作用 2. 脚本类与方法2.1 ToolGroup 脚本类2.2 ToolBlock 脚本类2.3 Job 脚本类 3. 脚本使用案例3.1 Job脚本&#xff1a;自动调节曝光时间3.2 ToolBlock脚本&…

【Django】django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

其中django后台manage.py入口程序报错&#xff0c;检索很多问题解决方案&#xff0c;这里记录下个人问题原因 1.django启动异常问题详情 django.core.exceptions.AppRegistryNotReady: Apps aren’t loaded yet. 2.问题原因 Python第三方包安装版本不一致或缺少依赖包&…

江西智博环境| 邀您参加2024全国水科技大会暨技术装备成果展览会

展位号&#xff1a;A28 企业介绍 江西智博环境技术有限公司始创于2008年初&#xff0c;总部位于江西省域副中心城市-赣州。公司主要从事一体化净水设备、单村供站、泵船、无负压供水设备自动化控制系统、低配电系统、工艺设备及智慧水务的设计研发、生产、销售、安装、调试等业…

[练习]用Js获取html页面中表单提交的数据并且返回到控制台

代码地址​​​​​​​​​​​​​​​​​​​​​&#xff1a; ​​​​​​​将前端页面提交的数据返回到前端控制台 Dduo/前端学习仓库 - 码云 - 开源中国 (gitee.com) 效果图 项目结构 html <!DOCTYPE html> <html lang"en"> <head><…

spring版本介绍

Spring Framework 是一个广泛使用的 Java 平台&#xff0c;用于构建企业级应用程序。它提供了一个全面的编程和配置模型&#xff0c;支持现代 Java 应用程序的最佳实践&#xff0c;如依赖注入、面向切面编程以及基于注解的编程模型。自从 Spring 1.0 发布以来&#xff0c;已经经…

Android14 - WindowManagerService之客户端Activity布局

Android14 - WindowManagerService之客户端Activity布局 一、主要角色 WMS作为一个服务端&#xff0c;有多种客户端与其交互的场景。我们以常见的Activity为例&#xff1a; Activity&#xff1a;在ActivityThread构建一个Activity后&#xff0c;会调用其attach方法&#xff0c;…