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

简介: <<和>>操作符、取地址重载、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对象中某一成员变量的地址,获取指定的内容的时候

相关文章
|
3天前
|
数据采集 人工智能 安全
|
12天前
|
云安全 监控 安全
|
4天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1046 151
|
4天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
17天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1732 9
|
9天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
682 152
|
11天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
646 12
|
6天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
408 4