运算符重载,就是赋予运算符具有操作自定义类型数据功能。运算符重载的实质就是函数调用,它的格式是:返回值 函数名(参数1,参数2...),但是又不同于普通函数。 运算符重载函数的函数名是用 operator+运算符 组成的。返回值是运算完成后的值决定的。
1.运算符重载
运算符重载有两个方式:1.友元函数的方式重载
2.类的成员函数的方式重载
(1). 友元函数的方式重载
在类中申明运算符重载时需要在前缀加上friend修饰,友元函数方式的运算符重载,该函数是不属于类的,所以函数参数的个数等于运算符操作数的个数。
Class MM{
public:
MM(int age):age(age){ };
//友元函数的方式重载运算符
friend MM operator+(MM m1,MM m2){
return MM(m1.age+m2.age);
}
void print(){
cout<< age <<endl;
}
protected:
int age;
};
int main(){
MM m1(19);
MM m2(20);
//隐式调用运算符重载函数
MM m3 = m2 + m1;
//显式调用运算符重载函数
MM m3 = operator+(m1, m2);
m3.print();
return 0;
}
上述代码中,有关于调用运算符重载函数的两种方式(显示调用和隐式调用)。显示调用更好的说明了运算符重载的本质就是函数调用 。
(2).类的成员函数的方式重载
把运算符重载的函数变成类的成员函数,由于采用成员函数的形式重载,是属于类的,所以函数的参数就等于操作数-1(因为他的本质是通过对象调用,所以可以少写一个操作数)。
class MM{
public:
MM(int age) :age(age){ };
//友元函数的方式重载
friend MM operator+(MM m1, MM m2);
void print(){
cout << age << endl;
}
//类的成员函数的方式重载
MM operator-(MM m2){
return (this->age - m2.age);
}
protected:
int age;
};
MM operator+(MM m1, MM m2)
{
return MM(m1.age + m2.age);
}
int main(){
MM m1(19);
MM m2(20);
MM m3 = operator+(m1, m2);
//类的成员函数方式的显示调用运算符重载
MM m4 = m1.operator-(m2);
//类的成员函数方式的隐示调用运算符重载
MM m4 = m1 - m2;
m3.print();
}
2.流重载
关于我们输入输出流运算符<< >>的重载只能采用友元函数的方式来重载。cin 和 cout 都是 istream类和 ostream类的一个对象。之所以我们能用<< >>运算符来操作 istream 和 ostream来输入输出,就是因为istream 和 ostream 类中已经对流运算做了重载 。
class MM{
public:
MM(string name = " ", int age = 18) :name(name), age(age){
}
//根据cout cin 能连续输出输入 可以推断流重载返回的是流对象的引用
friend istream& operator>>(istream& in, MM& mm){
return in;
}
friend ostream& operator<<(ostream out, MM mm){
return out;
}
protected:
string name;
int age;
};
根据cout cin 能连续输出输入 可以推断流重载返回的是流对象的引用。
3.++ --运算符重载
前置运算符和后置运算符相比,后置运算符多了一个无用的参数int
class MM
{
public:
MM(string name ,int age):name(name),age(age){}
MM operator++(int) //后置运算符 需要一个无用参数 充当标记
{
//return MM(name,age++);
}
MM operator++() //前置运算符,不需要int
{
return MM(name, ++age);
}
protected:
string name;
int age;
};
4.类的对象的隐式转换
operator除了重载运算符,还能对类进行隐式转换 : operator + 需要被转换的类型
如下:
class MM
{
public:
MM(string name ,int age):name(name),age(age){}
//类的对象的隐式转换 operator
operator int()
{
return age;
}
protected:
string name;
int age;
};
int main(){
MM mm("xx",28);
//进行了类的隐式转换
int MMage=mm;
return 0;
}
总结:
-
= () -> [] 只能采用类的成员函数形式重载
-
流重载采用友元方式
-
. .* ?: :: 不能重载