1. 通过操作符重载,程序员能针对类类型的操作数定义不同的操作符版本。
2. 重载操作符是具有特殊名称的函数:保留字operator后接需定义的操作符符号。
重载操作符的形参数目(包括this指针)要与操作符的操作数数目相同。例如:二元操作符则需要两个形参;一元操作符只需要一个形参。
3. 重载操作符必须具有至少一个类类型或枚举类型的操作数。这条规则强制重载操作符不能重定义用于内置类型对象的操作符的含义。
4. 成员函数和非成员函数:1)当重载操作符是成员函数,有隐含的this指针,形参数目会比操作数少一个 2)当重载操作符不是成员函数,没有this指针,形参数目与操作数个数相同。
5. 使用重载操作符:
1)obj1 + obj2 2)operator+(obj1, obj2) 3)使用成员操作符:obj1.operator+(obj2) 其中,this指针指向obj1
6. 对于系统的所有操作符,一般情况下,只支持基本数据类型和标准库中提供的class,对于用户自己定义的class,如果想支持基本操作,比如比较大小,判断是否相等,等等,则需要用户自己来定义关于这个操作符的具体实现。
那么为什么叫重载呢?这是因为,在编译器实现的时候,已经为我们提供了这个操作符的基本数据类型实现版本,但是现在他的操作数变成了用户定义的数据类型class,所以,需要用户自己来提供该参数版本的实现。
7. 重载==后,考虑如下的if语句:
if(10==p1) cout<<”the age is equal!” 是否会正确执行呢?
答案是不会的,因为只有左操作数是该类类型的对象时,才会考虑作为类成员重载操作符。因为10不是person类型的对象,所以,不能调用classperson的重载操作符==。
考虑如下if语句:
if(person(10)==person(11))
cout<<"ok"
是否能够正确执行呢?答案是可以,因为操作符两边均是无名对象。
8. 重载操作符实例:
1)输出操作符<<重载 (注意:IO操作符必须为非成员函数)
#include<iostream>
using namespace std;
class CTest
{
public:
CTest(int m, float f):a(m),f(f){}
friend ostream& operator<<(ostream& out,const CTest& obj); //作为友元
private:
int a;
float f;
};
.cpp文件中:
ostream& operator<<(ostream& out,const CTest& obj)
{
out<<obj.a<<"\t"<<obj.f;
return out; //方便调用时多次输出
}
int main()
{
CTest test(5, 5.5);
operator<<(operator<<(cout, test),test); //输出两次。调用方式一。 直接使用cout
cout << test << test; //输出两次。调用方式二 。 直接使用cout
system("pause");
return 0;
}
2) 输入操作符>>重载
#include<iostream>
using namespace std;
class CTest
{
public:
friend istream& operator>>(istream& ii, CTest& obj);
public:
int a;
float f;
};
.cpp中
istream& operator>>(istream& ii, CTest& obj)
{
ii >> obj.a; //输入值放入obj.a中
return ii;
}
int main()
{
CTest test;
cin >> test >> test; //可以多次输入
cout<<test.a<<endl;
system("pause");
return 0;
}
3) 加法操作
作为非成员函数时:
#include<iostream>
using namespace std;
class CTest
{
public:
CTest(){}
CTest(int m, float f):a(m),f(f){}
friend CTest operator+(CTest& obj1, CTest& obj2);
public:
int a;
float f;
};
.cpp中:
CTest operator+(CTest& obj1, CTest& obj2)
{
int b = obj1.a + obj2.a;
float f = obj1.f + obj2.f;
CTest test(b, f);
return test; //返回后是值拷贝。可以的。
}
//CTest& operator+(CTest& obj1, CTest& obj2)
//{
// int b = obj1.a + obj2.a;
// float f = obj1.f + obj2.f;
// CTest test(b, f);
// return test; //返回引用是错误的,因为退出函数后,栈空间释放。去掉&是值拷贝,正确方式
//}
int _tmain(int argc, _TCHAR* argv[])
{
CTest test1(1, 1.1);
CTest test2(2, 2.2);
CTest test3;
test3 = operator+(test1, test2); //调用方式一
test3 = test1 + test2; //调用方式二
cout<<test3.a<<endl;
cout<<test3.f<<endl;
system("pause");
return 0;
}
作为成员函数时:
#include<iostream>
using namespace std;
class CTest
{
public:
CTest(){}
CTest(int m, float f):a(m),f(f){}
CTest operator+(CTest& obj);
public:
int a;
float f;
};
.cpp中:
CTest CTest::operator+(CTest& obj)
{
int b = this->a + obj.a;
float f = this->f + obj.f;
CTest test(b, f);
return test;
}
int _tmain(int argc, _TCHAR* argv[])
{
CTest test1(1, 1.1);
CTest test2(2, 2.2);
CTest test3;
test3 = test1.operator +(test2); //作为成员函数的调用方式
cout<<test3.a<<endl;
cout<<test3.f<<endl;
system("pause");
return 0;
}
4) 相等判断
作为成员函数时,非成员函数省略。
#include<iostream>
using namespace std;
class CTest
{
public:
CTest(){}
CTest(int m, float f):a(m),f(f){}
bool operator==(CTest& obj);
public:
int a;
float f;
};
bool CTest::operator==(CTest& obj)
{
if (this->a == obj.a)
{
return true;
}
return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
CTest test1(1, 1.1);
CTest test2(1, 2.2);
if (test1.operator ==(test2))
{
cout<<"yes"<<endl;
}
system("pause");
return 0;
}