IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Cukor丘克说C++进阶02(上)2021-08-13 -> 正文阅读

[C++知识库]Cukor丘克说C++进阶02(上)2021-08-13

C++运算符重载

赋予运算符新的含义,让运算符直接操作自定义类型(类或结构体)。在C++中运算符能直接操作基本数据类型,但是不能直接操作自定义类型,所以为了方便开发人员的开发,就出现了运算符重载的概念,达到快速开发的效果。

运算符重载方式

  • 友元函数重载
  • 类的成员函数重载

重载的基本语法:
重载函数的返回值类型 operator 要重载的运算符(参数) { 函数体 ;}

参数个数:

  • 友元重载 重载函数的参数个数等于运算符的操作数
  • 类成员函数重载,重载函数参数个数是等于运算符的操作数-1

运算符重载函数的返回值类型是由通过这个要重载的运算符进行运算之后得到的最终结果来决定。而函数体的内部就是看我们自己怎么定义这个自定义类型在这个运算符下的操作。

直接上代码看看

友元函数重载:

#include<iostream>
using namespace std;

class MM
{
public:
	//利用缺省的方式写构造函数
	MM(string name="小可爱",int faceScore=0):name(name),faceScore(faceScore){}
	//重载‘+’
	friend MM operator+(MM mm1, MM mm2);
	void print();
protected:
	string name;
	int faceScore;
};

int main()
{
	MM mm1("Alice", 100);
	MM mm2("Coco", 80);
	MM mm3 = mm1 + mm2;	//两个对象相加,没写运算符重载函数之前是错的
	mm3.print();
	//打印:AliceCoco       180
	return 0;
}

MM operator+(MM mm1, MM mm2)
{
	//实现重载:两个对象的姓名连接,两个对象的颜值相加
	return MM(mm1.name+mm2.name,mm1.faceScore+mm2.faceScore);
}

void MM::print()
{
	//直接打印信息
	cout << name << '\t' << faceScore << endl;
}

类的成员函数重载:

#include<iostream>
using namespace std;

class MM
{
public:
	//利用缺省的方式写构造函数
	MM(string name="小可爱",int faceScore=0):name(name),faceScore(faceScore){}
	//重载‘+’
	MM operator+(MM mm);
	void print();
protected:
	string name;
	int faceScore;
};

int main()
{
	MM mm1("Alice", 100);
	MM mm2("Coco", 80);
	MM mm3 = mm1 + mm2;	//两个对象相加,没写运算符重载函数之前是错的
	mm3.print();
	//打印:AliceCoco       180
	return 0;
}

MM MM::operator+(MM mm)
{
	return MM(this->name+mm.name,this->faceScore+mm.faceScore);
}

void MM::print()
{
	//直接打印信息
	cout << name << '\t' << faceScore << endl;
}

从友元函数重载和类的成员函数重载可以看到二者的区别,友元函数没有this是因为友元函数不属于类,所以this不明确。类的成员函数是因为这个函数是属于类的this指的就是当前对象的首地址。因此友元的操作数等于参数个数,类的成员函数的操作数等于参数减1。

注意点:运算符重载不能违背原来的含义,也就是原来是类型一样的才能相加等操作,实现重载后也是一样。

即使能重载运算符,也不要重载得太离谱。

运算符重载的隐式调用和显式调用

运算符重载后,对象使用运算符的过程就是调用运算符重载函数的过程,调用有分非为隐式调用和现实调用,两种方法都可以调用到运算符重载函数,然后执行函数中的内容。一般来说,为了书写方便,采用的是隐式调用的方法进行调用。

隐式调用

重载什么运算符就直接像平常使用运算符一样使用就可以了

简单例子:

//这里已经封装好一个MM类,类中的属性是姓名和颜值
//并且在类中已经重载了 '+' 运算符
//然后在主函数中就可以直接使用'+'
MM mm1("A",10);
MM mm2("B",20);
MM mm3=mm1+mm2;
//那么mm3的姓名属性就是AB
//mm3的颜值属性就是30

完整的代码测试:

//重载减号
#include<iostream>
using namespace std;

class MM
{
public:
    MM(string name = "Alice", int faceScore = 100) :name(name), faceScore(faceScore) {}
    //友元重载
    friend MM operator-(MM mm1, MM mm2);
    void print()
    {
        cout << this->name << '\t' << this->faceScore << endl;
    }
protected:
    string name;
    int faceScore;
};

int main()
{
    MM mm1("美女一号", 100);
    MM mm2("美女二号", 60);
    MM mm3 = mm1 - mm2;	//隐式调用,就直接使用 '-' 运算符
    mm3.print();
    //打印:美女一号	40
    return 0;
}

MM operator-(MM mm1, MM mm2)
{
    //简单点写就不把名字相减了,就直接是颜值这一属性相减
    return MM(mm1.name,mm1.faceScore-mm2.faceScore);
}

显式调用

//重载运算符简单案例
#include<iostream>
using namespace std;

class MM
{
public:
	MM(string name="Alice",int faceScore=3):name(name),faceScore(faceScore){}
	//友元重载
	friend MM operator+(MM mm1, MM mm2);
	//类的成员函数重载
	MM operator-(MM mm);
	void print();
protected:
	string name;
	int faceScore;
};

int main()
{
	//测试代码
	MM mm1("A", 20);
	MM mm2("B", 60);
	MM mm3 = mm1 + mm2;	//隐式调用
	MM mm4("C",80);
	mm4 = mm4.operator-(mm1);	//显式调用	类的成员函数是这样做的
	MM mm5("D", 70);
	mm5 = operator+(mm1, mm2);	//显式调用	友元函数是这样的
	//打印
	mm3.print();
	mm4.print();
	mm5.print();
	return 0;
}

MM operator+(MM mm1, MM mm2)
{
	//重载的效果是名字相连,颜值相加
	return MM(mm1.name+mm2.name,mm1.faceScore+mm2.faceScore);
}

MM MM::operator-(MM mm)
{
	//使用原来的名和两个颜值相减
	return MM(this->name,this->faceScore-mm.faceScore);
}

void MM::print()
{
	cout << name << '\t' << faceScore << endl;
}

注意项:

  • 一般情况下单目重载使用类的成员函数方式重载双目使用友元函数方式重载

  • 使用运算符重载的时候尽量不要违背本意

  • 有些运算符不能被重载:

    • ? : 三目运算符
    • . 点
    • :: 作用域分辨符
    • .*
    • ->*
  • 必须采用类的成员函数重载:

    • ()
    • []
    • =
  • 流重载必须采用友元函数重载

    • <<
    • >>

简单的案例

重载 ‘=’ 运算符

#include<iostream>
using namespace std;

class Student
{
public:
	Student(string name="",int age=0):name(name),age(age){}
	//重载 '=' 运算符只能使用类的成员函数重载
	Student operator=(Student stu);
	void print();
protected:
	string name;
	int age;
};

int main()
{
	Student Cukor("Cukor", 20);
	Student newPerson;
	//使用运算符测试之前先打印:
	cout << "使用运算符之前:" << endl;
	Cukor.print();
	newPerson.print();
	//使用运算符
	newPerson.operator=(Cukor);	//显式调用
	cout << "使用了运算符之后:" << endl;
	Cukor.print();
	newPerson.print();
	return 0;
}

Student Student::operator=(Student stu)
{
	//函数内部进行赋值操作
	this->name = stu.name;	
	this->age = stu.age;
	return *this;	//返回对象本身
}

void Student::print()
{
	cout << name << '\t' << age << endl;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 13:50:50  更:2021-08-14 13:50:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 16:22:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计