<<和>>操作符、取地址重载、const关键字

news2025/2/21 21:36:00

在这里插入图片描述

文章目录

  • 自定义类型<<和>>重载
  • const关键字
  • 取地址重载(类的默认构造函数)


自定义类型<<和>>重载

在内置类型中,<<和>>可以自动识别

在自定义类型冲,运算符重载,<<和>>也可以重载,我们首先来认识一下,<<和>>

//>>流插入  将键盘输入的内容,赋值到变量中
//<<流提取	 将cout后面的内容输出到屏幕中

int main()
{
    int a;
    double b;
    Date date;//自定义类型输出的形式,系统无法规定(自定义类型的成员变量不同),所以需要<<和>>重载
    cin>>a>>b;//系统可以自动识别类型
    cout<<a<<" "<<b<<endl;
    return 0;
}

在这里插入图片描述

<iostream>是C++中的输入输出流,istream是输入流,ostream是输出流(这样理解即可)

std::ostream::operator<<我们看到编译器对于内置类型进行了处理,接下来以Date类为例子,进行操作符<<重载

对于<<和>>总结

1.可以直接支持内置类型是因为库中实现了

2.可以直接支持自动识别类型是因为函数重载,传入对应类型的参数就可以调用对应的函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//Date
class Date
{
public:
     void operator<<(ostream& out);//我们使用的成员函数,所以默认this占用一个成员形参,调用这个函数的形式为  对象名.operator<<(cout)
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};
void Date::operator<<(ostream& out)
{
    out << _year << " " << _month << " " << _day << endl;
}
int main()
{
    Date date1(2010, 10, 10);
    Date date2(1012, 1, 10);
    Date date3(2001, 10, 10);

    date1.operator<<(cout);  //等同于date1<<cout
    //但是这一种明显不是我们需要的cout<<int  这种类型,所以我们要实现的是cout<<date1
    return 0;
}

为了实现cout<<date1 这样的写法,我们要使得ostream形参在前面,Date对象在后面,但是如果是在成员函数中,this对象总是占据第一个位置,date1.operator<<(cout) 实际上就是相当于,传递两个参数,第一个参数是this(date1),第二个参数才是为cout,所以为了解决这个问题(先调用cout(cout在前面)),我们应该使用全局函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//Date
class Date  //我们使用全局函数可以使得第一个参数为cout 从而实现cout<<date1 
{			//但是全局函数不在类中,无法使用私有成员变量,所以我们应该使用friend(在不破化原有封装性的基础上,打开一个口子,只是使得这个函数成为类似于共有函数(可以访问d的私有成员))
public:
    friend ostream& operator<<(ostream& out, const Date& d);//传入形参为ostream类型,也就是输出流,传引用,那么
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};
//但是我们知道 cout<<int<<int  是库里支持的所以我们应该返回ostream来实现这个功能
ostream& operator<<(ostream& out, const Date& d)
{
    out << d._year << " " << d._month << " " << d._day << endl;//调用这个函数就可以输出我们规定的内容
    return out;
}//传引用返回
int main()
{
    Date date1(2010,10,10);
    Date date2(1012, 1, 10);
    Date date3(2001, 10, 10);

    cout << date1<<date2<<date3;
    return 0;
}

所以上面这个代码是最为符合库中对于内置类型的重载的,使用ostream&返回,并使用全局函数来实现cout在前,实例化成员在后,且可以连续<<

>>和<<是一个道理,都是istream&为返回值,然后使用传参先是istream& in 然后再是第二个参数const Date& d

//例子如下
class Date{
    public:
    friend istream& operator>>(istream& in,const Date& d);
    private:
    	int _year;
    	int _month;
    	int _day;
};
     istream& operator>>(istream& in,const Date& d)
     {
         //需要进行判断是否是合理的年月日,根据自定义类型成员变量的需求进行更改
         //这里就不去写判断日期是否合理
        int year, month, day;
		in >> year >> month >> day;
     }
int main()
{
    Date d;
    ///然后就可以实现流插入————插入进去,流提取————提取出来
    cin>>d;
    Date d1,d2,d3;
    cin>>d1>>d2>>d3;
    return 0;
}

上文就是对于流插入和流提取的运算符重载,主要内容就是使用istream&/ostream& 引用返回,使得第一个变量位置给了istream& in/ostream& out,第二个形参位置给了自定义类型

iostream是c++的标准库,里面包括但不限于istream(标准输入类)ostream(标准输出类)

const关键字

const的基本用法为,修饰变量或者是指针,使得其不能改变数值,或指向

//在C++中多了一种对于const的用法
class Date{
  public:
    Date(int year,int month,int day)
    {
        _year=year;
        _month=month;
        _day=day;
    }
    void Print() const  //使用const来修饰的是this指针  也就是 const Date* this,使得this指向的成员变量不能被改变
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
  private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    
    return 0;
}

const修饰指针的时候,如:const Date* this,不能改变的是this的成员变量,指针的指向是可以变化的

const修饰变量的时候,如:Date* const this,不能改变的是指针的指向,但是this的成员变量是可以变化的

const同时修饰指针和变量的时候,如:const Date* const this,指针的指向和this的成员变量都不能改变
在这里插入图片描述

请思考下面的几个问题:

  1. const对象可以调用非const成员函数吗?
  2. 非const对象可以调用const成员函数吗?
  3. const成员函数内可以调用其它的非const成员函数吗?
  4. 非const成员函数内可以调用其它的const成员函数吗?

对于上述问题,我们通过下面代码测试的得到答案

1.const对象不能调用非const的成员函数

2.非const对象是可以调用非const修饰的成员函数/const修饰的成员函数

3.const成员函数内,不能调用非const成员函数

4.非const成员函数内,可以调用非const修饰的成员函数/const修饰的成员函数

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>

using namespace std;

//在C++中多了一种对于const的用法
class Date {
public:
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    void Print() const  //使用const来修饰的是this指针  也就是 const Date* this,使得this指向的成员变量不能被改变
    {
        cout << _year << "-" << _month << "-" << _day << endl;
        //这是const修饰的成员函数
        Print2();//说明不能调用非const函数
    }
    void Print2() {
        Print();//说明可以调用const修饰的函数
    }
    void plus_year()
    {
        _year++;
    }
    
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1(1, 1, 1);
    const Date d2(2, 2, 2);//创建两个变量,分别为非const和const修饰
    d1.Print();
    d2.Print();//调用const修饰的函数,说明是可以的

    d1.plus_year();
    d2.plus_year();//const修饰的成员不能调用非const修饰的成员
    return 0;
}

下面的对于const的一些小问题,权限可以变小,但是不能放大

int main()
{
    const int a=10;
    int b=a;  //这一个是正确的,因为只是将a的数值拷贝赋值给b,b的改变不会影响a,所以正确
    
    const int c=10;
    int& d=c;	//这是错误的,因为d引用c,使得d可以改变c(c不能被改变),const变量权限小于普通变量,涉及到权限放大,所以这是错误的
    
    const int e=10;
    int*pf=&e;	//错误,这个和引用是类似的,都是涉及到权限放大
    return 0;
}

取地址重载(类的默认构造函数)

前面四个类中默认的成员函数都已经学习,我们来学习一下剩下这两个取地址重载的默认成员函数

取地址重载主要就是针对普通成员和const对象取地址,但是这两个会自己去实现,实际上使用默认的即可

class Date{
  public:
    Date* operator&()  //对于普通成员
    {
        cout<<"非const"<<endl;
        return this;//取地址,返回的是指针类型
    }
    Date* operator&() const
    {
        cout<<"const"<<endl;
        return this;//对于const修饰的成员
    }
};
int main()
{
    Date d1;
    const Date d2;
   	Date* d3=&d1;
    const Date* d4=&d2;
    return 0;
}

在这里插入图片描述

一般来说,使用编译器默认的取地址重载即可,但是对于一些特殊情况是可以使用取地址重载的,比如说,只是取出来这个this对象中某一成员变量的地址,获取指定的内容的时候

在这里插入图片描述

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

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

相关文章

maven从入门到精通 第六章 在Maven中项目导入、生命周期、插件、目标、仓库

这里写自定义目录标题 一 工程与模块导入1 工程导入的方法1.1 版本控制系统1.2 来自工程目录1.2.1 直接导入工程文件1.2.2直接解压 2 模块导入 二 生命周期的基本概念1 生命周期存在的意义 三 插件和目标四 仓库 一 工程与模块导入 1 工程导入的方法 1.1 版本控制系统 通常使…

有赞一面:亿级用户DAU日活统计,有几种方案?

说在前面 在40岁老架构师 尼恩的读者社区(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如极兔、有赞、希音、百度、网易、滴滴的面试资格&#xff0c;遇到一几个很重要的面试题&#xff1a; (1) 亿级用户场景&#xff0c;如何高性能统计日活&#xff1f; (2) 如何实现亿…

九、Ribbon负载均衡

目录 一、Ribbon负载均衡策略&#xff08;常用7种&#xff09;&#xff1a; 详细介绍&#xff1a; 1、轮询策略&#xff1a; RoundRibbonRule&#xff08;Ribbon默认策略&#xff09; 2、重试策略&#xff1a;RetryRule 3、加权响应时间策略&#xff1a;WeightedResponseT…

【模拟电子技术】常用半导体器件——本征半导体

&#x1f347;&#x1f347;只有强大的意志&#xff0c;才能成就最艰难的选择。 ——CSDN厉昱辰 目录 &#x1f34d;&#x1f34d;一、半导体 &#x1f34d;&#x1f34d;二、本征半导体的晶体结构 &#x1f34d;&#x1f34d; 三、本征半导体中的两种载流子 &#x1f34d…

数字图像处理基础知识(自救指南)

概念 本部分多来自课件&#xff0c;见水印 数字图像处理的目的 提高图像的视感质量&#xff0c;以达到赏心悦目的目的。提取图像中所包含的某些特征或特殊信息&#xff0c;主要用于计算机分析&#xff0c;经常用作模式识别、计算机视觉的预处理。对图像数据进行变换、编码和压…

炫云为什么要采用让人看不懂的GHZ计费?

很多人看到炫云GHZ计费都表示看不懂&#xff0c;觉得麻烦&#xff0c;没有按核数、按线程或者按分钟计费简单易懂&#xff0c;甚至还被某些同行经常拿来攻击。哪为什么炫云还坚持用GHZ计费呢&#xff1f;哪是因为使用GHZ计费更加公平、透明&#xff0c;且具有硬件无关性。今天就…

10个适合Web开发的最佳CSS生成器工具

在写CSS的时候&#xff0c;我们可以手写CSS&#xff0c;也可以直接使用一些CSS生成器来完成&#xff0c;今天我就跟大家分享10个好用的CSS生成器工具&#xff0c;帮助你提升工作效率。 1.纯CSS条纹生成器 网址&#xff1a;https://stripesgenerator.com 没有 Flash&#xff0…

QT多线程基础

文章目录 前言一、多线程概念介绍二、创建一个线程三、start和terminate函数四、如何不使用terminate函数终止线程总结 前言 本篇文章来讲解一下QT中的多线程使用方法。 其实线程这个概念对于我们来说并不陌生&#xff0c;main函数在多线程中一般就被称为主线程。 在QT中&am…

《计算机网络—自顶向下方法》 第四章Wireshark实验:TCP 协议分析

在因特网协议族&#xff08;Internet Protocol Suite&#xff09;中&#xff0c;TCP 层是位于 IP 层之上&#xff0c;应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接&#xff0c;但是 IP 层不提供这样的流机制&#xff0c;而是提供不可靠的包交换。…

Ordinal 是什么? BTC NFT 解释

Ordinal NFT 于 2023 年 1 月 20 日由开发者 Casey Rodarmor 在 BTC 主网上推出&#xff0c;它是在 BTC上 创建 NFT 的最新方式。虽然 BTC 上的 NFT 并不是一个新概念&#xff0c;BTC 之上的第 2 层网络&#xff08;例如 Counterparty 和 Stacks&#xff09;已经支持基于 BTC 的…

第七届中华梦乡·福清石竹山梦文化节举办

第七届中华梦乡福清石竹山梦文化节现场 5月9日至12日&#xff0c;第七届中华梦乡福清石竹山梦文化节暨海峡两岸&#xff08;福清&#xff09;道教论坛在福州福清举办。本届梦文化节以“福佑中华 梦圆石竹”为主题&#xff0c;旨在发挥海峡两岸道教界同根同源、联系密切的独特优…

【Java零基础入门篇】第 ⑤ 期 - 抽象类和接口(二)

博主&#xff1a;命运之光 专栏&#xff1a;Java零基础入门 学习目标 1.了解什么是抽象类&#xff0c;什么是接口&#xff1b; 2.掌握抽象类和接口的定义方法&#xff1b; 3.理解接口和抽象类的使用场景&#xff1b; 4.掌握多态的含义和用法&#xff1b; 5.掌握内部类的定义方法…

【HBase】介绍

文章目录 什么时候用Hbase&#xff1f;常见应用场景逻辑结构物理结构数据模型Name Space TableRowColumnTime StampCell 存储设计HLogHFileHfile生成方式 Apache HBase™ 是以 hdfs 为数据存储的&#xff0c;一种分布式、可扩展的 NoSQL 数据库。 Bigtable 是一个稀疏的、分布式…

5项目五:W1R3S-1(思路为主!)

特别注明&#xff1a;本文章只用于学习交流&#xff0c;不可用来从事违法犯罪活动&#xff0c;如使用者用来从事违法犯罪行为&#xff0c;一切与作者无关。 目录 前言 一、信息收集 二、网页信息的收集 三、提权 总结 前言 思路清晰&#xff1a; 1.信息收集&#xff0c;…

《程序员面试金典(第6版)》面试题 16.19. 水域大小(深度优先搜索,类似棋盘类问题,八皇后的简化版本,C++)

题目描述 你有一个用于表示一片土地的整数矩阵land&#xff0c;该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小&#xff0c;返回值需要从小到…

【数据结构与算法】图的遍历与拓扑排序

文章目录 一、用数组模拟邻接表二、图的深度优先遍历&#xff08;dfs&#xff09;2.1 概念2.2 例题&#xff1a;树的重心 三、图的广度优先遍历&#xff08;bfs&#xff09;3.1 概念3.2 例题&#xff1a;图中点的层次 四、拓扑排序4.1 概念4.2 例题&#xff1a;有向图的拓扑序列…

2直接连接的网络与VLAN划分-2.2【实验】【计算机网络】

2直接连接的网络与VLAN划分-2.2-2.3【实验】【计算机网络】 前言推荐2直接连接的网络与VLAN划分2.1共享式以太网和交换式以太网2.2交换机MAC地址表建立与帧转发实验目的实验内容及实验环境实验原理交换机通过逆向学习帧的源地址&#xff0c;构建MAC地址表;交换机中MAC地址的构建…

netty基础(五)

1.基本介绍 1>.异步的概念和同步相对.当一个异步过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的组件在完成后,通过状态、通知和回调来通知调用者; 2>.Netty中的I/O操作是异步的,包括Bind、Write、Connect等操作会简单的返回一个 ChannelFuture; 3>.调用…

二、Eureka注册中心

目录 注册中心主要有三种角色&#xff1a; 1、服务提供者&#xff08;RPC Server&#xff09; 2、服务消费者&#xff08;RPC Client&#xff09; 3、服务注册中心&#xff08;Registry&#xff09; 注册中心实现原理 常用的注册中心&#xff1a; 常用注册中心对比&…

【C/C++每日一练】总目录(更新至2023.5.12)

C/C 2023.05 2023.5.11-2023.5.12 20230512 1. 成绩打印 ※ 2. 按要求补齐数组 &#x1f31f;&#x1f31f;&#x1f31f; 3. 水仙花数 ※ 20230511 1. 最长公共前缀 &#x1f31f; 2. 打家劫舍 &#x1f31f;&#x1f31f; 3. 最接近的三数之和 &#x1f31f;&am…