zoukankan      html  css  js  c++  java
  • 第四章 运算符重载

    运算符重载

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

    等号=重载

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

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

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

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

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

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

      • 返回值应为ClassName&voidClassName有缺陷[1]

        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]
    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. 定义为成员函数时,无参数[3]

      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 ↩︎

  • 相关阅读:
    [Swift]LeetCode1109. 航班预订统计 | Corporate Flight Bookings
    [Swift]LeetCode1110. 删点成林 | Delete Nodes And Return Forest
    [Swift]LeetCode1111. 有效括号的嵌套深度 | Maximum Nesting Depth of Two Valid Parentheses Strings
    Live 2D所有模型展示图
    [Swift]LeetCode1108. IP 地址无效化 | Defanging an IP Address
    [CocoaPods]CocoaPods无法使用:Shell终端切换bash和zsh
    [Swift]完全透明沉浸式导航栏
    转 open_cursors参数设置调优
    模拟IO 读写压力测试
    转 DG switchover
  • 原文地址:https://www.cnblogs.com/DreamEagle/p/12632015.html
Copyright © 2011-2022 走看看