运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
- 重载后运算符的优先级和结合性不变
- 运算符操作数的个数不能改变
- 不能重载C++中不支持的运算符(@、#、$等)
- 保持运算符的语义
基本格式:
返回值 [类名] operator 运算符 (形参表){}
加号重载
作用:实现两个自定义数据类型相加的运算
class myint
{
public:
int n;
myint() {};
myint(int _n) { n = _n; };
myint operator+(myint& a)
{
myint temp;
temp = this->n + a.n;
return temp;
}
};
int main()
{
myint test0(3),test1(5);
cout << (test0 + test1).n << endl;//8
}
减号运算符重载与此类似。
左移运算符重载
左移右移只能重载为类的友元函数(需要写为全局函数,访问类的私有对象就需要友元)。
左移返回输出流,右移返回输入流对象。
class myint
{
private:
int n;
public:
friend ostream& operator<<(ostream& cout, myint& a);
myint(int _n) { n = _n; };
};
ostream& operator<<(ostream& cout, myint& a)
{
cout << a.n << "\n";
return cout;//返回输出流对象
}
int main()
{
myint test(3);
cout << test;
}
递增运算符重载
前置++可以返回一个引用,但后置++只能返回值,不能返回原对象的引用。
class myint
{
public:
int n;
myint(int _n) { n = _n; };
myint& operator++()
{
this->n++;
return *this;
}
myint operator++(int)//占位符
{
myint temp(0);
temp.n = this->n;
记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;
this->n++;
return temp;
}
};
int main()
{
myint test(3);
//都为4
cout << (++test).n << endl;
cout << (test++).n << endl;
}
赋值运算符重载
此处涉及到深浅拷贝问题。在此以深拷贝为例。
class myint
{
private:
int* n;
public:
myint() {};
myint(int _n) { n = new int(_n); };
myint& operator=(myint& example)
{
if (this == &example)
return *this;//自赋值检测,防止浪费空间
this->n = new int(*example.n);
return *this;
}
void get_p() { cout<<n<<" "<<*n<<endl; };
};
int main()
{
myint test0(3),test1;
test1 = test0;
test0.get_p();
test1.get_p();
}
[ ] 运算符重载
可以防止数组越界。
class int_array
{
private:
int* _array;
int size;
public:
int_array(int n)
{
size = n; _array = new int[size];
for (int i = 0; i < size; i++)
{
this->_array[i] = i;
}
};
int operator[](int n)
{
if (n < 0 || n >= size)
{
cout << "array bound";
exit(1);
}
return this->_array[n];
}
};
int main()
{
int_array test(10);
cout << test[5];
}
()运算符重载
在 C++ 中,类型的名字(包括类的名字)本身也是一种运算符,即类型强制转换运算符。
类型强制转换运算符是单目运算符,也可以被重载,但只能重载为成员函数,不能重载为全局函数。
经过重载后,(类型名)对象这个对对象进行强制类型转换的表达式就等价于 对象.operator 类型名()
,即变成对运算符函数的调用。
#include <iostream>
using namespace std;
class Complex
{
double real, imag;
public:
Complex(double r = 0, double i = 0) :real(r), imag(i) {};
operator double() { return real; } //重载强制类型转换运算符 double
};
int main()
{
Complex c(1.2, 3.4);
cout << (double)c << endl; //输出 1.2
double n = 2 + c; //等价于 double n = 2 + c. operator double()
cout << n; //输出 3.2
}