本文主要介绍C++中的重载操做符(operator)的相关知识。ios
1. 概述
1.1 what
operator 是C++的一个关键字,它和运算符(如=)一块儿使用,表示一个运算符重载函数,在理解时可将operator和运算符(如operator=)视为一个函数名。函数
使用operator重载运算符,是C++扩展运算符功能的方法。使用operator扩展运算符功能的缘由以下:this
使重载后的运算符的使用方法与重载前一致
扩展运算符的功能只能经过函数的方式实现(实际上,C++中各类“功能”都是由函数实现的)
1.2 why
对于C++提供的全部操做符,一般只支持对于基本数据类型和标准库中提供的类的操做,而对于用户本身定义的类,若是想要经过该操做符实现一些基本操做(好比比较大小,判断是否相等),就须要用户本身来定义关于这个操做符的具体实现了。spa
好比,咱们要设计一个名为“person”的类,如今要判断person类的两个对象p1和p2是否同样大,咱们设计的比较规则是按照其年龄来比较,那么,在设计person类的时候,就能够经过对操做符“==”进行重载,来使用操做符“==”对对象p1和p2进行比较了(根据前面的分析,实际上比较的内容应该是person类中的数据成员“age”)。设计
咱们上面说的对操做符“==”进行重载,说是“重载”,是因为编译器在实现操做符“==”功能的时候,已经为咱们提供了这个操做符对于一些基本数据类型的操做支持,只不过因为如今该操做符所操做的内容变成了咱们自定义的数据类型(如class),而默认状况下,该操做符是不能对咱们自定义的class类型进行操做的,因此,就须要咱们经过重载该操做符,给出该操做符操做咱们自定义的class类型的方法,从而达到使用该操做符对咱们自定义的class类型进行运算的目的。对象
1.3 how
实现一个操做符重载的方式一般分为两种状况:编译器
将操做符重载实现为类的成员函数;
操做符重载实现为非类的成员函数(即全局函数)。
1.3.1 将操做符重载实现为类的成员函数
在类体中声明(定义)须要重载的操做符,声明方式跟普通的成员函数同样,只不过操做符重载函数的名字是“关键字 operator +以及紧跟其后的一个C++预约义的操做符”,样式以下(person是咱们定义的类):string
bool operator==(const person& ps)
{
if (this->age == ps.age)
{
return true;
}
return false;
}
示例代码(operator_test2.cpp)以下:it
#include <iostream>
using namespace std;
class person
{
private:
int age;
public:
person(int nAge)
{
this->age = nAge;
}
bool operator==(const person& ps)
{
if (this->age == ps.age)
{
return true;
}
return false;
}
};
int main()
{
person p1(10);
person p2(10);
if (p1 == p2)
{
cout << "p1 is equal with p2." << endl;
}
else
{
cout << "p1 is not equal with p2." << endl;
}
return 0;
}
编译并运行上述代码,结果以下:io
经过上述结果可以知道:由于操做符重载函数“operator==”是person类的一个成员函数,因此对象p一、p2均可以调用该函数。其中的 if (p1 == p2) 语句,至关于对象p1调用函数“operator==”,把对象p2做为一个参数传递给该函数,从而实现了两个对象的比较。
1.3.2 操做符重载实现为非类的成员函数(即全局函数)
对于全局重载操做符,表明左操做数的参数必须被显式指定。
示例代码以下:
#include <iostream>
using namespace std;
class person
{
public:
int age;
};
// 左操做数的类型必须被显式指定
// 此处指定的类型为person类
bool operator==(person const& p1 ,person const& p2)
{
if (p1.age == p2.age)
{
return true;
}
else
{
return false;
}
}
int main()
{
person p1;
person p2;
p1.age = 18;
p2.age = 18;
if (p1 == p2)
{
cout << "p1 is equal with p2." << endl;
}
else
{
cout << "p1 is NOT equal with p2." << endl;
}
return 0;
}
编译并运行上述代码,结果以下:
1.3.4 操做符重载的方式选择
能够根据如下因素,肯定把一个操做符重载为类的成员函数仍是全局函数:
若是一个重载操做符是类成员,那么只有当与它一块儿使用的左操做数是该类的对象时,该操做符才会被调用;而若是该操做符的左操做数肯定为其余的类型,则操做符必须被重载为全局函数;
C++要求'='、'[]'、'()'、'->'操做符必须被定义为类的成员操做符,把这些操做符经过全局函数进行重载时会出现编译错误
若是有一个操做数是类类型(如string类),那么对于对称操做符(好比==操做符),最好经过全局函数的方式进行重载。
1.3.5 操做符重载的限制
实现操做符重载时,须要注意:
重载后操做符的操做数至少有一个是用户定义类型; 不能违反原来操做数的语法规则; 不能建立新的操做符; 不能重载的操做符包括(以空格分隔):sizeof . .* :: ?: RTTI类型运算符 =、()、[]、以及 ->操做符只能被类的成员函数重载 1.3.6 操做符重载的详细用法 赋值运算符的重载函数(operator=),点击此处