运算符重载为友元函数
- 一般情况下,将运算符重载为类的成员函数是较好的选择
- 但有时,重载为成员函数不能满足使用需求,重载为普通函数又不能访问类的私有成员,故要将运算符重载为友元
- 例如
class Complex
{
double real,imag;
public:
Complex(double r,double i):real(r),imag(i){};
Complex operator+(double r);
};
Complex Complex::operator+(double r)
{
return Complex(real+r,imag);
}
Complex c;
c=c+5;//有定义,相当于c=c.operator+(5);
c=5+c;//编译出错
Complex operator + (double r,const Complex & c)
{
return Complex(c.real+r,c.imag);
}
//要使普通函数能够访问其私有成员real和imag所以需要设置友元
class Complex
{
double real,imag;
public:
Complex(double r,double i):real(r),imag(i){};
Complex operator+(double r);
friend Complex operator+(double r,const Complex & c);
};
运算符重载的实例:可变长整型数组
int main(){//要编写可变长整型数组类,使之能如下使用
CArray a;//开始数组是空的
for(int i=0;i<5;++i)
a.push_back(i);//要用动态内存分配来存放数组元素,需要一个指针成员变量
CArray a2,a3;
a2=a;//要重载`=`
for(int i=0;i<a.length();++i)
cout<<a2[i]<<" ";//要重载`[]`
a2=a3;//a2是空的
for(int i=0;i<a2.length();++i)//a2.length()返回0
cout<<a2[i]<<" ";
cout<<endl;
a[3]=100;
CArray a4(a);//要自己写复制构造函数
for(int i=0;i<a4.length();++i)
cout<<a4[i]<<" ";
return 0;
}
class CArray{
int size;//数组元素的个数
int *ptr;//指向动态分配的数组
public:
CArray(int s=0);//s代表数组元素的个数
CArray(CArray &a);
~CArray();
void push_back(int v);//用于在数组尾部添加一个元素v
CArray & operator = (const CArray & a);//用于数组对象间的赋值
int length(){ return size;}//返回数组元素个数
int & CArray ::operator[](int i)//返回值不能用int,不支持a[i]=4
{//用以支持根据下标访问数组元素,如`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){//如果a是空数组
ptr=NULL;
size=0;
return;
}
ptr=new int[a.size];//如果a非空
memcpy(ptr,a.ptr,sizeof(int)*a.size);
size=a.size;
}
CArray::~CArray(){//析构函数
if(ptr) delete[]ptr;
}
CArray & CArray::operator=(const CArray & a)
{
if(ptr==a.ptr)//防止a=a这样的赋值导致出错
return *this;
if(a.ptr==NULL){//如果a是空数组
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 push_back(int v)
{//在尾部添加一个元素
if(ptr){
int * tmpPtr=new int[size+1];//重新分配空间
memcpy(tmpPtr,ptr,sizeof(int)*size);//拷贝原数组的内容
delete[]ptr;
ptr=tmpPtr;
}
else//数组本来是空的
ptr=new int[1];
ptr[size++]=v;//加入新的数组元素
}