运算符重载

对已有的运算符赋予多重的含义
扩展c++中提供的运算符的使用范围,以用于不同的类型

运算符重载基本概念

  • 运算符重载为普通函数
 class Complex{
 public:
     double real;double imag;
     Complex(double r=0.0,double j=0.0){
         real=r;imag=j;
     }
 protected:
 private:

 };

 Complex operator+(const Complex & i1,const Complex & i2){
     return Complex(i1.real+i2.real,i1.imag+i2.imag);
 }

int main(){
    Complex a(1,2),b(3,4),c;
    c=a+b;
    cout <<c.real<<"--"<<c.imag<<endl;
    return 0;
}

输出:
4–6

  • 运算符重载为成员函数
class Complex{
public:
    Complex(double a=0,double b=0):real(a),imag(b){}
    Complex operator+(const Complex & i1);
    Complex operator-(const Complex & i1);
    void print(){
        cout<<real<<"--"<<imag<<endl;
    }
protected:
private:
    double real,imag;
};

Complex Complex::operator+(const Complex & i1 ){
    return Complex(i1.real+real,i1.imag+imag);
}

Complex Complex::operator-(const Complex & i1){
    return Complex(i1.real-real,i1.imag-imag);
}

int main(){
    Complex a(1,2),b(4,5),c,d;
    c=a+b;
    d=a-b;
    c.print();d.print();
    return 0;
}

注意:参数个数为运算符个数-1

  • 运算符重载为友元函数
class Complex{
private:
    int real,imag;
public:
    Complex(int a=0,int b=0):real(a),imag(b){}
    void print(){
        cout << real << " + i" << imag << endl;
    }
    friend Complex operator+(const Complex & i1,const Complex & i2);
};

Complex operator+(const Complex & i1,const Complex & i2){
    return Complex(i1.real+i2.real,i2.imag+i1.imag);
}

int main(){
    Complex a(1,3),b(4,5);
    Complex c=a+b;
    //d=a-b;
    c.print();//d.print();
    return 0;
}

赋值运算符重载

例1:

class String{
private:
    char *str;
public:
    String():str(NULL){}
    const char *c_str(){
        return str;
    }
    char *operator=(const char *s);
    ~String();
};

char *String::operator=(const char *s){
    if (str)
        delete []str;
    if (s){
        str=new char[strlen(s)+1];
        strcpy(str,s);
    }else
        str=NULL;
    return str;
}

String::~String(){
    if (str)
        delete []str;
}


int main(){
    String s;
    s="first";
    cout<<s.c_str()<<endl;
    s="second";
    cout<<s.c_str()<<endl;
    return 0;
}

这里写图片描述

  • 浅拷贝
    这里写图片描述

逐个字节拷贝

  • 深拷贝
    这里写图片描述

将一个对象中变量所指向的内容,复制到另一个对象中指针成员对象所指的地方

class String{
private:
    char *str;
public:
    String():str(NULL){}
    ~String();
    const char *string_out(){return str;}
    String & operator=(const String & s);
    char * operator=(char *s);
};

char* String::operator=(char *s){
    if (str)
        delete []str;
    if (s ){
        str=new char[strlen(s )+1];strcpy(str,s );
    }else
        str=NULL;
    return str;
}

String & String::operator=(const String & s){
    if (str)
        delete []str;
    if (s.str){
        str=new char[strlen(s.str)+1];strcpy(str,s.str);
    }else
        str=NULL;
    return *this;
}

String::~String(){
    if (str)
        delete []str;
}

int main(){
    String a,b;
    a="44";b="33";
    cout<<a.string_out()<<endl;
    cout<<b.string_out()<<endl; 
    a=b;cout<<a.string_out()<<endl;
    return 0;
}

这里写图片描述


  • 思考1
int main(){
    String a,b,c;
    a="44";
    a=a;
    cout<<a.string_out()<<endl;
    return 0;
}

这里写图片描述

程序会出错
正确的程序 :

String& String::operator=(const String & s){
    if (str==s.str)
        return *this;
    if (str)
        delete []str;
    if (s.str){
        str=new char[strlen(s.str)+1];strcpy(str,s.str);
    }else
        str=NULL;
    return *this;
}
  • 对operator=的返回值的讨论

void 类型的返回值
a=b=c; 此时程序出错


  • 没有引用

1、返回类型如果不是对象的引用:

具体步骤是:
(1)释放元内存资源
(2)申请一块新的内存空间
(3)原堆内存的值赋值到新的内存
(4)创建临时对象(调用拷贝构造函数),返回临时对象
(5)临时对像结束,调用析构函数,释放对象内存

2、返回类型如果是对象的引用:

具体步骤:
(1)释放原内存资源
(2)申请新的内存资源
(3)原值赋值到新的内存
(4)结束

返回对象的引用 不需要调用拷贝构造函数,提高效率,建议采纳。

C++ - 创建动态数组

class CArray{
private:
    int size;int *ptr;
public:
    CArray(int s=0);
    ~CArray();
    CArray(const CArray & a);
    void push_back(int v);
    int length(){return size;}
    int & operator[](int i);
    CArray & operator=(const CArray & a);
};

int & CArray::operator[](int i){
    return ptr[i];
}

CArray::CArray(int s){
    size=s;
    if (s==0){
        //delete []ptr;
        ptr=NULL;
    }else
        ptr=new int[s];
}

CArray::~CArray(){
    size=0;
    if (ptr)
        delete []ptr;
}

CArray::CArray(const CArray & a){
    if (a.ptr==NULL){
        size=0;delete []ptr;ptr=NULL;return;
    }
    ptr=new int[a.size];size=a.size;
    memcpy(ptr,a.ptr,sizeof(int)*a.size);
}

void CArray::push_back(int v){
    if (ptr==NULL){
        ptr=new int[1];
    }else{
        int *tem1=new int[size+1];
        memcpy(tem1,ptr,sizeof(int)*size);
        delete []ptr;ptr=tem1;
    }
    ptr[size++]=v;
}



CArray & CArray::operator=(const CArray & a){
    if (ptr==a.ptr)
        return *this;
    if (!a.ptr){
        if(ptr){
            delete []ptr;ptr=NULL;size=0;return *this;
        }
    }
    if (a.ptr){
        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;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    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;
}

自加自检运算符重载

为待完续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值