this指针
重载()
可以避免函数指针的出现,STL的仿函数就是实现了operator()
,使类具有了类似函数的行为
1.概述
operator 是C++的一个关键字,它和运算符(如=)一起使用,表示一个操作符重载函数,在理解时可将operator和运算符(如operator=)视为一个函数名。使用operator重载运算符,是C++扩展运算符功能的方法。使用operator扩展运算符功能的原因如下:
-
使重载后的运算符的使用方法与重载前一致
-
扩展运算符的功能只能通过函数的方式实现(实际上,C++中各种“功能”都是由函数实现的)
2.为什么要重载操作符
对于C++提供的所有操作符,通常只支持对于基本数据类型和标准库中提供的类的操作,而对于用户自己定义的类,如果想要通过该操作符实现一些基本操作(比如比较大小,判断是否相等),就需要用户自己来定义关于这个操作符的具体实现了。
比如,我们要设计一个名为“person”的类,现在要判断person类的两个对象p1和p2是否一样大,我们设计的比较规则是按照其年龄来比较,那么,在设计person类的时候,就可以通过对操作符“==”进行重载,来使用操作符“==”对对象p1和p2进行比较了(根据前面的分析,实际上比较的内容应该是person类中的数据成员“age”)。
我们上面说的对操作符“==”进行重载,说是“重载”,是由于编译器在实现操作符“==”功能的时候,已经为我们提供了这个操作符对于一些基本数据类型的操作支持,只不过由于现在该操作符所操作的内容变成了我们自定义的数据类型(如class),而默认情况下,该操作符是不能对我们自定义的class类型进行操作的,所以,就需要我们通过重载该操作符,给出该操作符操作我们自定义的class类型的方法,从而达到使用该操作符对我们自定义的class类型进行运算的目的。
3.怎样实现操作符的重载
通常实现操作符重载有两种方式:
-
将操作符重载实现为类的成员函数
-
操作符重载实现为非类的成员函数(即全局函数)
操作符重载的方式选择:
-
如果一个重载操作符是类成员,那么只有当与它一起使用的左操作数是该类的对象时,该操作符才会被调用;而如果该操作符的左操作数确定为其他的类型,则操作符必须被重载为全局函数;
-
C++要求'='、'[]'、'()'、'->'操作符必须被定义为类的成员操作符,把这些操作符通过全局函数进行重载时会出现编译错误
-
如果有一个操作数是类类型(如string类),那么对于对称操作符(比如==操作符),最好通过全局函数的方式进行重载。
4.操作符重载的限制
-
重载后操作符的操作数至少有一个是用户定义类型;
-
不能违反原来操作符的语法规则;
-
不能创建新的操作符;
-
不能重载的操作符包括(以空格分隔):sizeof . .* :: ?: RTTI类型运算符
-
=、()、[]、以及 ->操作符只能被类的成员函数重载
重载bool()
class A
{
public:
explicit operator bool()const noexcept { return false; }
};
int main()
{
A a;
if (a); //如果不重载bool()此处编译器会报错
}
示例代码(实现重载[]、==、())
点击查看代码
#include <iostream>
#include <string>
class MyClass
{
public:
int arr[5];
int flag; //用来实现重载==
MyClass(int n):
flag(n)
{
for (int i = 0; i < 5; i++)
{
arr[i] = i * n;
}
}
int& operator[] (const int &i) //重载[]
{
return arr[i];
}
//bool operator==(const MyClass& c) //重载==
//{
// if (this->flag == c.flag)
// return true;
// return false;
//}
std::string operator()(std::string str) //重载()
{
return str;
}
};
//全局函数实现重载操作符==
bool operator==(const MyClass& c1, const MyClass& c2)
{
if (c1.flag == c2.flag)
return true;
return false;
}
int main()
{
MyClass c(2);
std::cout << "c[1] = " << c[1] << std::endl;
c[2] = 666; //因为重载[]返回的是引用,所以此处才可以修改c[2]
std::cout << "c[2] = " << c[2] << std::endl;
MyClass c1(2);
MyClass c2(3);
std::cout << "c == c1?" << (c == c1) << "\nc == c2?" << (c == c2) << std::endl;
std::cout << c("重载()") << std::endl;
return 0;
}