c++学习记录(十二)

运算符重载为友元函数

  • 一般情况下,将运算符重载为类的成员函数是较好的选择
  • 但有时,重载为成员函数不能满足使用需求,重载为普通函数又不能访问类的私有成员,故要将运算符重载为友元
  • 例如
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;//编译出错
  • 所以为了使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;//加入新的数组元素
}
原文地址:https://www.cnblogs.com/2002ljy/p/12283610.html