欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

第四章 运算符重载

程序员文章站 2022-03-20 15:45:40
[TOC] 运算符重载 1. 定义: 重新定义运算符的运算 2. 实质是函数重载,把含有运算符的表达式转换成对运算符函数的调用 3. 可以重载为普通函数、成员函数、友元函数 重载成普通函数,参数表个数=运算符目数 重载为友元函数,可访问私有成员,同时解决重载为成员函数操作数顺序不满足条件的问题 重载 ......

目录

运算符重载

  1. 定义:重新定义运算符的运算
  2. 实质是函数重载,把含有运算符的表达式转换成对运算符函数的调用
  3. 可以重载为普通函数、成员函数、友元函数
    • 重载成普通函数,参数表个数=运算符目数
    • 重载为友元函数,可访问私有成员,同时解决重载为成员函数操作数顺序不满足条件的问题
    • 重载为成员函数,参数表个数=运算符目数-1
  4. 多次重载时,根据实参类型决定调用哪个运算符函数

等号=重载

  1. 等号只能重载为成员函数

  2. 赋值语句和初始化语句的等号=含义不同,初始化语句需要用构造函数实现

  3. 同类赋值注意点(可能包含指针)

    • 浅拷贝:采用默认的赋值号,导致指针指向同一个地址,原有动态分配内存未释放,且数据相互影响

    • 深拷贝:释放原有内存空间,并重新动态分配一块内存

    • 在拷贝前应检查是否拷贝自身(即if(this=&s),会造成自身内部空间先被是否,复制出错),是则直接return *this

    • 返回值应为classname&voidclassname有缺陷

      a=b=c; //连续赋值,void不行
      (a=b)=c; //结果为a=c; classname不行
      
    • 使用复制拷贝函数时,需要考虑类似的问题

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

变长数组

  1. 非引用的函数返回值不能作为左值使用
  2. 赋值和初始化时采用深拷贝

流插入&流提取运算符重载

  1. coutcin分别是ostreamistream类的对象,类中分别对<<>>运算符进行了重载

  2. 可全局重载>><<运算符,使其满足要求

    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 substr=s.substr(0,pos);
    	c.real=stod(substr);
    	int pos2=s.find('i',0);
    	c.imag=stod(s.substr(pos+1,pos2));
    	return is;
    }
    

类型转换运算符重载

  1. 不写返回值(返回值即转换类型)

  2. 定义为成员函数时,无参数

    class complex{
    	double real,imag;
    	public:
    		complex(double r=0,double i=0):real(r),imag(i){};
    		operator double (){ return real; } //将complex类强制转换成double类
    };
    
    
  3. 包含了显式类型转换和自动类型转换

    complex c(1.2,3.4);
    cout<<(double) c<<endl;
    double tmp=5+c;
    cout<<tmp<<endl;
    

自增自减运算符重载

  1. 前置(作为一元运算符处理),返回值为引用

    //成员函数
    t& operator++();
    t& operator--();
    //普通函数
    t& operator++(t& c); 
    t& operator--(t& c);
    
  2. 后置(作为二元运算符处理),返回值不是引用,效率没前置的高

    //成员函数
    t operator++(int);
    t operator--(int);
    //普通函数
    t operator++(t& t,int);
    t operator--(t& t,int);
    
  3. 示例

    cdemo& operator--(cdemo &c){
    	c.n--;
    	return c;
    }
    cdemo operator--(cdemo &c,int){
    	cdemo tmp(c);
    	c.n--;
    	return tmp;
    }
    

运算符重载注意事项

  1. c++不允许定义新运算符
  2. 重载后运算符应符合日常习惯
  3. 运算符重载不改变运算符优先级
  4. 不能被重载的运算符:.,.*,::,?:,sizeof
  5. 重载运算符(),[],->,或赋值运算符=时,运算符重载函数必须声明为类成员函数

  1. 运算符重载时,应尽量保留运算符原有的特性

  2. 不能被赋值

  3. 成员函数参数个数=操作数-1