(一)运算符重载的基本概念
运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。
运算符重载的实质就是函数重载。在实现过程中,首先把指定的运算表达式转化为运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要对运算符重载的规则用的函数,这个过程是在编译过程中完成的。
-
运算符重载赋予运算能够操作自定义类型。
-
运算符重载前提条件: 必定存在一个自定义类型
-
运算符重载实质: 就是函数调用
-
友元重载
-
类重载
-
-
在同一自定义类型中,一个运算符只能被重载一次
-
C++重载只能重载已有的运算符,不能重载没有
-
C++重载一般情况不能违背运算符原来的含义(就算语法正确);
-
重载之后运算符的优先级和结合性都不会变
-
注意点:
-
C++标准规定,有些操作符是不能重载的,它们是类属关系运算符“.”、成员指针运符.*”、作用域分辨符“::”和三目运算符“?:”。前面两个运算符保证了C++语言中访问成员功能的含义不被改变。作用域分辨符的操作数是类型,而不是普通的表达式,也不具备重载的特征。
-
-
函数的一般语法形式为:
函数返回值类型 函数名(参数)
{
//函数体;
}
//运算符重载也是函数,只是函数名写法不同
//函数名: operator加上运算符组成函数名
//参数:
// 友元重载: 参数个数等于操作数
// 类成员函数: 参数个数等于操作-1
// 函数返回值类型:运算符组成表达式 最终结果是什么类型就返回类型
// int a; int b; a+b 返回int
// 函数体:写你真正要实现的效果注意:返回类型指定了重载运算符的返回值类型,也就是运算结果类型;operator 是定义运算符重载函数的关键字;运算符即是要重载的运算符名称,必须是C++中可重载的运算符,比如要重载加法运算符,这里就写“+”;形参表中给出重载运算符所需要的参数和类型。
(二)友元重载
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM() {}
MM(string name, int score) :name(name), score(score) {}
void print()
{
cout << name << "\t" << score << endl;
}
//友元重载
friend MM operator+(MM a, MM b); //加法重载函数的声明
protected:
string name;
int score;
};
MM operator+(MM a, MM b)
{
return MM(a.name+b.name, a.score + b.score); //返回一个匿名对象
}
int main()
{
int a = 1;//基本数据类型运算符直接用
int b = 2;
int sum = a + b;
MM mm("小芳", 6);
MM girl("芳", 2);
//error: 没有与这些操作数匹配 "xxx" 运算符
//重载函数的隐式调用 -->mm + girl 解析为:operator+(mm, girl)
MM result = mm + girl;
result.print();
//重载函数显示调用:按照函数的调用方式
MM res = operator+(mm, girl); //operator+:函数名 参数
return 0;
}
(三)类重载
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM() {}
MM(string name, int score) :name(name), score(score) {}
void print()
{
cout << name << "\t" << score << endl;
}
MM operator-(MM object);
protected:
string name;
int score;
};
//类成员函数少一个参数: 对象本身可以表示参数
MM MM::operator-(MM object)
{
return MM(this->name , this->score - object.score);
}
int main()
{
MM mm("小芳",6);
MM girl("芳", 2);
MM mul = mm.operator-(girl); //类重载显示调用,跟调用普通成员函数一样的
mul.print();
MM girlFriend = mm - girl; //重载隐示调用:编译器mm - girl翻译为: mm.operator-(girl)
girlFriend.print();
return 0;
}
(四)特殊重载
-
通常情况:单目运算符用类成员函数重载,双目用友元重载
-
= ,(),->,[] 只能采用成员函数重载
-
++ --运算符重载
-
增加一个无用参数,标识是后置++或者--
-
-
流运算符重载(>> <<)
-
输入流对象(cin): istream类
-
输出流对象(cout): ostream类
-
流重载必须用引用
-
流重载一定要用友元重载
-
-
后缀重载
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM() {}
MM(string name, int age) :name(name), age(age) {}
void print()
{
cout << name << "\t" << age << endl;
}
//MM operator=(MM) = delete;//删掉默认的
void operator=(int data)
{
this->age += data;//age=age+data;
}
friend ostream& operator<<(ostream& out, MM& object);
friend istream& operator>>(istream& in, MM& object);
//++ 为例
MM operator++() //前置
{
this->age++;
return *this; //先加一;返回对象本身
}
MM operator++(int) //后置的
{
return MM(this->name, this->age++);
}
protected:
string name;
int age;
};
ostream& operator<<(ostream& out, MM& object)
{
//out当做cout用
out << object.name << "\t" << object.age << endl;
return out;
}
istream& operator>>(istream& in, MM& object)
{
cout << "输入对象属性:";
//in当做cin用即可
in >> object.name >> object.age;
return in;
}
int main()
{
MM mm("小芳",6);
MM girl;//MM girl("芳", 2);
girl = mm;//默认=
girl = 8;
girl.print();
MM result = ++girl;
result.print();
girl.print();
result = girl++;
result.print();
girl.print();
cin >> girl;
cout << girl << endl;
return 0;
}
文本重载:一般写成下划线系列;