1.运算符重载:
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进行的操作。运算符函数的定义与其他函数的定义类似,惟一的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。运算符函数定义的一般格式如下:
<返回类型说明符> operator <运算符符号>(<参数表>)
{
<函数体>
}
2.运算符重载遵循的规则:
- 除长度运算符sizeof、条件运算符: ?、成员选择符.和域解析运算符::。c++其他运算符都可以被重载
- 重载不能改变运算符的优先级和结合性
c1 = c2+c3*c4 //相当于c1 = c2+(c3*c4) 乘法优先级依然高于加法优先级
-
重载不会改变运算符的用法,原来有几个操作数、操作数在左边还是在右边,重载后一样
-
重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
-
运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。
-
运算符重载函数既可以作为类的成员函数,也可以作为全局函数
3.类成员函数:
- 将运算符重载函数作为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的
创建格式:
<对象名>.operator <运算符>(<参数>)
=>
<对象名><运算符><参数>
例如:a+b 等价于 a.operator +(b)。一般情况下,我们采用第一种
实例:
complex operator+(const complex & A) const;
c3 = c1 + c2; // 被转换为 c3 = c1.operator+(c2); 通过this指针隐式的访问c1的成员变量
4.全局函数:
- 将运算符重载函数作为全局函数时,二元操作符就需要两个参数,一元操作符需要一个参数,而且其中必须有一个参数是对象,好让编译器区分这是程序员自定义的运算符,防止程序员修改用于内置类型的运算符的性质
- 如果有两个参数,这两个参数可以都是对象,也可以一个是对象,一个是C++内置类型的数据,例如:
complex operator+(int a, complex &c){
return complex(a+c.real, c.imag);
}
//另外,将运算符重载函数作为全局函数时,一般都需要在类中将该函数声明为友元函数。原因很简单,该函数大部分情况下都需要使用类的private成员。
5.友元函数
运算符重载为类的友元函数的一般格式为:
friend <函数类型> operator <运算符>(<参数表>)
{
<函数体>
}
当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。
调用友元函数运算符的格式如下:
operator <运算符>(<参数1>,<参数2>)
=>
<参数1><运算符><参数2>
例如:a+b等价于operator +(a,b)。
程序代码:
1.字符串类
class String
{
public:
String(char * ptr)
{
mptr = new char[strlen(ptr)+1]();
strcpy_s(mptr,strlen(ptr)+1,ptr);
}
~String()
{
delete[]mptr;
mptr = NULL;
}
String& operator(const String& rhs)
{
if(this != &rhs)
{
delete[]mptr;
mptr = new char[strlen(rhs.mptr)+1]();
strcpy_s(mptr,strlen(rhs.mptr)+1,rhs.mptr);
}
return this;
}
//拷贝构造
String(const string& rhs)
{
mptr = new char[strlen(rhs.mptr)+1]();
strcpy_s(mptr,strlen(rhs.mptr)+1,rhs.mptr);
}
const String operator+(char* ptr)//thiscall
{
char* pnewchar = new char[strlen(mptr) + strlen(ptr) + 1]();
strcpy_s(pnewchar, strlen(mptr) + 1, mptr);
strcat(pnewchar, ptr);
String tmp(pnewchar);
delete[] pnewchar;
return tmp;
}
bool operator<(const String& rhs)
{
return strcmp(mptr, rhs.mptr) < 0;
}
std::ostream& operator<<(std::ostream& out)
{
out << mptr;
return out;
}
bool operator!=(const String& rhs)
{
return strcmp(mptr, rhs.mptr) != 0;
}
char& operator[](int index)//arr[0] = 10;
{
return mptr[index];
}
private:
char* mptr;
friend const String operator+(char*, const String&);
friend std::ostream& operator<<(std::ostream&, const String&);
};
const String operator+(char* ptr, const String& rhs)//_cdecl
{
char* pnewchar = new char[strlen(ptr) + strlen(rhs.mptr) + 1]();
strcpy_s(pnewchar, strlen(ptr) + 1, ptr);
strcat(pnewchar, rhs.mptr);
String tmp(pnewchar);
delete[] pnewchar;
return tmp;
}
std::ostream& operator<<(std::ostream& out, const String& rhs)
{
out << rhs.mptr;
return out;
}
};
int main()
{
String str1("hello");
String str2("world");
String str3 = str1 + "hi";
str3 = "hi" + str2;
if (str1 < str2)//strcmp
{
std::cout << str3 << std::endl;//ostream
}
if (str1 != str3)
{
std::cout << str1[0] << std::endl;
}
return 0;
}
Test 类
class Test
{
public:
Test(int a) :ma(a){}
private:
friend Test operator+-(Test&, int);
int ma;
};
Test operator+-(Test& a,int b)
{
return Test(a.ma - b);
}
int main()
{
int a = 10;
int b = 20;
int c = a + b;
return 0;
}
复数类
复数类型的加法运算:实部加实部,虚部加虚部
1.重载 " + ":
CComplex CComplex:: operator+(const CComplex &src)
{
return CComplex(src.mreal + mreal, src.mimage + mimage);
}
2.全局函数:
CComplex operator+(const CComplex &lhs, const CComplex &rhs)
// 定义为全局 可实现类似 comp4 = 10 + comp3,左边参数会进行隐式转换
{
return CComplex(lhs.mreal + rhs.mreal, lhs.mimage + rhs.mimage);
}
3.重载输入输出操作符" << “、” >> ":
iostream& operator<<(iostream &out, const CComplex &src)
{
out << "mreal = " << src.mreal << ", mimage = " << src.mimage << endl;
return out;
}
iostream& operator>>(iostream &in, CComplex &src) // 不能声明为const 因为要进行修改
{
in >> src.mreal >> src.mimage;
return in;
}
4.重载" += "操作符
void CComplex :: operator+=(const CComplex &src)
{
mreal += src.mreal;
mimage += src.mimage;
}
5.重载前置自增操作符
CComplex& CComplex :: operator++()
{
mreal++;
mimage++;
return *this;
}
6.重载后置自增操作符:
// 后置单目运算符重载为类的成员函数时,函数要带有一个整型形参。
CComplex CComplex :: operator++(int)
{
return CComplex(mreal++, mimage++);
}
CComplex类:
class CComplex
{
public:
CComplex(int real = 0, int mage = 0):mreal(real), mimage(mage) {};
CComplex operator+(const CComplex &src);
void operator+=(const CComplex &src);
CComplex operator++(int);
CComplex& operator++();
private:
int mreal;
int mimage;
friend istream& operator>>(istream &in, CComplex &src);
friend iostream& operator<<(iostream &out, CComplex &src);
friend CComplex operator+(const CComplex &lhs, const CComplex &rhs);
};
CComplex CComplex:: operator+(const CComplex &src)
{
return CComplex(src.mreal + mreal, src.mimage + mimage);
}
ostream& operator<<(ostream &out, const CComplex &src)
{
out << "mreal = " << src.mreal << ", mimage = " << src.mimage << endl;
return out;
}
istream& operator>>(istream &in, CComplex &src) // 不能声明为const 因为要进行修改
{
in >> src.mreal >> src.mimage;
return in;
}
void CComplex :: operator+=(const CComplex &src)
{
mreal += src.mreal;
mimage += src.mimage;
}
CComplex CComplex :: operator++(int)
{
return CComplex(mreal++, mimage++);
}
CComplex& CComplex :: operator++()
{
mreal++;
mimage++;
return *this;
}
CComplex operator+(const CComplex &lhs, const CComplex &rhs)
// 定义为全局 可实现类似 comp3 = 10 + comp2,左边参数会进行隐式转换
{
return CComplex(lhs.mreal + rhs.mreal, lhs.mimage + rhs.mimage);
}
int main()
{
CComplex com(10, 10);
cout << com;
CComplex com1(20, 10);
com1 += com;
cout << com1;
CComplex com2;
com2 = com + com1;
cout << com2;
CComplex com3 = com2++;
cout << com3;
cout << com2;
com3 = ++com2;
cout << com3;
cout << com2;
CComplex com4;
cin >> com4;
cout << com4;
com4 += com1;
cout << com4;
com4 = com1 + 10;
cout << com4;
com4 = 10 + com1;
cout << com1;
cout << com4;
}