运算符重载
运算符重载,就是对已有的运算符赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为,作用就是扩展c++中已有运算符的范围,使之可以作用于对象,同一运算符对不同操作数,所发生的行为是不同的
- 运算符的重载的实质是函数重载
- 可以重载为普通函数,也可以重载为成员函数
- 把含运算符的表达式转换成对运算函数的调用
- 运算符被多次重载时,根据实参类型确定
重载为成员函数时,参数个数为运算符目数减一,重载为普通函数时参数个数为运算符目数
赋值运算符的重载
赋值运算符只能重载为成员函数
运算符重载为友元函数
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
class Complex
{
public:
double real, imag;
void Print(){
cout << real << ',' << imag;
}
Complex(double r, double i):real(r), imag(i)
{}
Complex operator+(double r);
};
Complex Complex::operator+(double r)
{
return Complex(real + r, imag);
}
上面的代码中c = c + 5是正确的但是c = 5 + c就是不对的,所以需要再重载
可变长数组
class CArray
{
int size;
int *ptr;
public:
//s代表数组元素个数
CArray(int s = 0);
CArray(CArray &a);
~CArray();
//用于在数组尾部添加一个元素v
void push_back(int v);
CArray& operator=(const CArray& a);
int length(){return size;}
int& CArray::operator[](int i)
{
//用以支持根据下标访问数组中的元素
//如n = a[i]和a[i] = 4这样的语句
return ptr[i];
}
};
CArray::CArray(int s):size(s)
{
if(s == 0) ptr = NULL;
else ptr = new int [s];
}
CArray::CArray(CArray &a)
{
if(!a.ptr)
{
ptr = NULL;
size = 0;
return ;
}
ptr = new int[a.size];
memcpy(ptr, a.ptr, sizeof(int)* a.size);
size = a.size;
}
CArray::~CArray()
{
if(ptr) delete []ptr;
}
CArray& CArray::operator=(const CArray& a)
{
//防止a = a这样出错
if(ptr == a.ptr) return *this;
//如果数组为空
if(a.ptr == NULL)
{
if(ptr) delete []ptr;
ptr = NULL;
size = 0;
return *this;
}
if(size < a.size)
{
if(ptr) delete []ptr;
ptr = new int [a.size];
}
memcpy(ptr, a.ptr, sizeof(int)*a.size);
size = a.size;
return *this;
}
void CArray::push_back(int v)
{
if(ptr)
{
int* tmp = new int[size + 1];
memcpy(tmp, ptr, sizeof (int)*size);
delete []ptr;
ptr = tmp;
}
else
ptr = new int[1];
ptr[size++] = v;
}
流插入运算符和流提取运算符的重载
cout 是在iostream中定义的ostream类的对象
ostream & ostream::operator<<(int n)
{
//输出要输出的内容
return *this;
}
#include<iostream>
#include <algorithm>
#include <cstring>
using namespace std;
class Complex
{
double real, imag;
public:
Complex(double r = 0, double i = 0):real(r), imag(i){};
friend ostream & operator << (ostream & os, const Complex& c);
friend istream & operator >> (istream & is, const Complex& c);
};
ostream & operator << (ostream & os, const Complex& c)
{
os << c.real << '+' << c.imag << 'i';
return os;
}
istream & operator >> (istream & is, Complex & c)
{
string s;
is >> s;
int pos = s.find("+", 0);
string sTmp = s.substr(0, pos);
c.real = atof(sTmp.c_str());
sTmp = s.substr(pos + 1, s.length() - pos - 2);
c.imag = atof(sTmp.c_str());
return is;
}
自增自减运算符的重载
自增运算符++、自减运算符有前置和后置之分,为了区分所重载的是前置运算符还是后置运算符,c++规定前置运算符作为一元运算符重载
//重载为成员函数
T & operator++();
T & operator--();
//重载为全局函数
T1 & operator++(T2);
T1 & operator--(T2);
//重载为成员函数
T & operator++(int);
T & operator--(int);
//重载为全局函数
T1 & operator++(T2, int);
T1 & operator--(T2, int);
- C++不允许定义新的运算符
- 运算符重载不改变运算符的优先级
- . 、.*、::、?:、sizeof不能被重载
- ()、[]、->或者=时运算符重载函数必须声明为类的成员函数