使对象的运算表现得和编译器内置类型一样。如我们想输出一个Complex,希望输出它的实部和虚部,那么我们只需要对<<进行重载即可。为什么不重载cout?因为cout是ostream类型的对象,系统已经给我们定义好了的,我们很难去对它ostream类进行重载。
下面是一个简单的复数类帮助我们理解运算符重载。
#include <iostream>
using namespace std;
//
// 复数类
//
class CComplex
{
public:
// CComplex() CComplex(20) CComplex(30,30)
CComplex(int r = 0, int i = 0) :mreal(r), mimage(i) { cout << "CComplex(int r = 0, int i = 0)" << endl; }
//指导编译器怎么做类对象的加法操作
//CComplex operator+(const CComplex& src)
//{
// /*CComplex comp;
// comp.mreal = this->mreal + src.mreal;
// comp.mimage = this->mimage + src.mimage;
// return comp;*/
// return CComplex(this->mreal + src.mreal, this->mimage + src.mimage);
//}
void show()
{
cout << "real:" << mreal << "image:" << mimage << endl;
}
CComplex operator++(int)
{
return CComplex(mreal++, mimage++);
}
CComplex& operator++()
{
mreal += 1;
mimage += 1;
return *this;
}
void operator+=(const CComplex& src)
{
mreal += src.mreal;
mimage += src.mimage;
}
private:
int mreal;
int mimage;
friend CComplex operator+(const CComplex& comp, const CComplex& src);
friend ostream& operator<<(ostream& out, CComplex const& src);
};
CComplex operator+(const CComplex& comp,const CComplex& src)
{
/*CComplex comp;
comp.mreal = this->mreal + src.mreal;
comp.mimage = this->mimage + src.mimage;
return comp;*/
return CComplex(comp.mreal + src.mreal, comp.mimage + src.mimage);
}
ostream& operator<<(ostream& out, CComplex const & src)
{
out << "mreal:" << src.mreal << "mimage:" << src.mimage << endl;
return out;
}
int main(void)
{
CComplex comp1(10, 10);
CComplex comp2(20, 20);
// comp1.operator+(com2) 加法运算符的重载函数
//
CComplex comp3 = comp1 + comp2;
comp3.show();
CComplex comp4 = comp1 + 10;//comp1.operator+(10);
comp4.show();
//编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法,就在全局作用域找合适的运算符重载函数 ::operator+(30,comp1)
CComplex comp5 = 10 + comp1;
comp5.show();
//CComplex operator(int){}
comp5 = comp1++;//++ --单目运算符 operator++()前置++ operator++(int)后置++
comp1.show();
comp5.show();
//CComplex operator(){}
comp5 = ++comp1;
comp1.show();
comp5.show();
/*CComplex* c = &(comp1++);*/
/*comp1++.operator=(comp5);*/
/*comp1.show();*/
comp1 += comp2;
comp1.show();
cout << comp1;
return 0;
}
再来看一个例子,这个例子中我们实现了一个简单的string类,来加深对运算符重载的理解。
#include <iostream>
using namespace std;
#include <string>
//自己实现一个字符串
class MyString
{
public:
MyString(const char* p = nullptr)
{
if (p != nullptr)
{
_pstr = new char[strlen(p) + 1];
strcpy(_pstr, p);
}
else
{
_pstr = new char[1];
_pstr[0] = '\0';
}
}
MyString(const MyString& str)
{
_pstr = new char[strlen(str._pstr) + 1];
strcpy(_pstr, str._pstr);
}
~MyString()
{
delete[]_pstr;
_pstr = nullptr;
}
MyString& operator +(const MyString& str)
{
if (this == &str)//排除自赋值
{
return *this;
}
delete[]_pstr;
_pstr = new char[strlen(str._pstr) + 1];
strcpy(_pstr, str._pstr);
return *this;
}
bool operator>(const MyString& str) const
{
return strcmp(_pstr, str._pstr) > 0;
}
bool operator<(const MyString& str) const
{
return strcmp(_pstr, str._pstr) < 0;
}
bool operator=(const MyString& str) const
{
return strcmp(_pstr, str._pstr) == 0;
}
int length()const
{
return strlen(_pstr);
}
char& operator[](int index)
{
return _pstr[index];
}
const char& operator[] (int index)const
{
return _pstr[index];//不能作为左值
}
const char* c_str()const
{
return _pstr;
}
private:
char* _pstr;
friend ostream& operator<<(ostream& out, const MyString& str);
friend MyString operator+(const MyString& str1, const MyString& str2);
};
MyString operator+(const MyString& str1, const MyString& str2)
{
char* ptmp = new char[strlen(str1._pstr) + strlen(str2._pstr) + 1];
strcpy(ptmp, str1._pstr);
strcat(ptmp, str2._pstr);
MyString tmp(ptmp);
delete[]ptmp;
return tmp;
/*return MyString(ptmp);*/
}
ostream& operator<<(ostream& out, const MyString& str)
{
out << str._pstr;
return out;
}
int main(void)
{
MyString str1;
MyString str2 = "aaa";
MyString str3 = "bbb";
MyString str4 = str2 + str3;
MyString str5 = str2 + "ccc";
MyString str6 = "ddd" + str2;
cout << "str6" << str6 << endl;
if (str5 > str6)
{
cout << str5 << ">" << str6 << endl;
}
else
{
cout << str6 << "<" << str6 << endl;
}
int len = str6.length();
for (int i = 0; i < len; ++i)
{
cout << str6[i] << " ";
}
cout << endl;
char buf[1024] = { 0 };
strcpy(buf, str6.c_str());
return 0;
}
此外,其实C++还有很多地方运用到了运算符重载,比如C++STL模板库里的iterator。