首页 > 其他分享 >运算符重载

运算符重载

时间:2023-10-20 09:36:24浏览次数:33  
标签:函数 int SYMBOL 运算符 operator 重载

运算符重载

1 概述

C++规定运算符重载必须针对类的对象,即重载时至少有一个参数是对象,如A、const A、A &等等。没有对象就new一个出来

C++用operator加运算符进行。对于普通运算符成员函数,this隐含参数代表第一个操作数对象。运算符可分为:

不能重载:sizeof、.、.*、::、?:
只能重载为普通成员函数:=、->、()、[]
只能重载为普通函数:new、delete
其他运算符可以重载为类的普通成员函数和普通函数,但不能重载为类的静态成员函数

若运算符为左值运算符,则重载后运算符应尽量返回非只读引用类型。当运算符要求第一个参数为左值时,不能使用const说明第一个参数(含this)。此外,重载不改变运算符的优先级和结合性。

需要注意,并不是含有类的名称的东西都是对象,如:

A &operator ==(A *a,A b[]);    //错误,这俩都是指针类型变量,不是对象

2 运算符参数

重载函数的参数个数与重载函数种类有关:

重载为普通函数:参数个数=运算符目数
重载为普通成员:参数个数=运算符目数-1(有一个this指针)
重载为静态成员:参数个数=运算符目数(没有this)

有些特殊的运算符不满足上述关系:->重载为单目,前置++--为单目,后置++--为双目,函数()可重载为任意目。

关于()运算符的重载,不加改动地照搬课件上令人难绷的代码。

#include <string.h>
class SYMTAB;
struct SYMBOL {
    char *name;  int  value;  SYMBOL *next;   friend SYMTAB;
private:
    SYMBOL(char *s, int v, SYMBOL *n)  { /*...*/ };   ~SYMBOL( ) { /*…*/ }
} *s;
class SYMTAB {
    SYMBOL *head;
public:
    SYMTAB( ) { head = 0; };     ~SYMTAB( )  { /*...*/  } 
    SYMBOL *operator( )(char *s, int v, int w) { /*…*/};
} tab;
void main(void) { s = tab(“a”, 1, 2); }   //等价 s = tab.operator()(“a”, 1, 2)

这里对SYMBOL类中的括号运算符重载为了三目运算符。

下面介绍一些特殊运算符。

2.1 自增自减

上面已经介绍了自增自减运算符的双目、单目两种情况。除此之外,还要声明一点:后置运算应返回右值,前置运算应返回左值。这样更方便对象的连续运算。

应注意,自增自减最好返回对象类型而非int,这更便于计算:

A operator++(int){    //后置
    return A(x++);    //巧妙的返回
}
A &operator++(){      //前置,返回引用类型
    x++;
    return *this;
}

2.2 双目箭头运算符

上面已经介绍,原先箭头运算符是双目的,重载应使其变成单目(只有一个参数)。重载->必须返回指针类型

下面是课件源代码,清晰地解释了语句i = b->a的含义,不再解释。

struct A { int a; A(int x) { a = x; } };
class  B {
    A  x;
public:
    A *operator ->( ) { return &x; };   //只有一个参数this, 为单目
    B(int v):x(v) {  }           //构造x(5)
} b(5);  
void  main(void) {
    int i = b->a;
    //上面语句翻译为:
    i = b.operator->( ) ->a;     //i = b.x.a = 5
    i = (*b.operator->( )).a;
}

可以看出,->重载的最大作用是简便代码的编写。

2.3 赋值

事实上,编译器为定义的类构造了缺省的赋值重载(浅拷贝)。即

A &operator=(const A&);

而若类自定义了重载赋值运算符函数,则会优先调用自定义的函数。

对于浅拷贝复制,若数据成员为指针类型,则不复制指针所指存储单元的内容。这可能会导致内存的泄露。因此对于成员包含指针的类,应尽量构造深拷贝赋值运算符重载函数。

为防止这种内存的泄露,可采用的方法有:

  1. 深拷贝,即先将指针指向的内容释放,再进行赋值和分配;

  2. 移动赋值,对纯右值使用,浅拷贝后令其指向nullptr我也不明白为什么这样可以防止内存泄漏

代码过于繁琐,详见课本相关内容。

3 强制类型转换

对类进行的强制类型转换同样可以进行重载。

需要强调的是,合适地编写构造函数可以利用构造函数直接进行类型转换。

class COMPLEX{
    double r,v;
public:
    COMPLEX(double r1);{/*...*/}
    COMPLEX(double r1,double v1);{/*...*/}
    COMPLEX operator+(const COMPLEX &c)const;
}
COMPLEX m(3);
cout<<m+2;

通过这种构造方式,3自动转化为double型的3.0m+2则转换为m+2.0,然后构造匿名对象COMPLEX(2.0),最终转换为m+COMPLEX(2.0)

而若想更清晰地表示强制类型转换,可以采用强制类型转换函数的方式:

operator 类型表达式()

如:

operator int()const{return i+j;}    //转换为int型
operator A()const{return A(i+j);}   //转换为类A型

对于newdelete的重载,不再解释。

标签:函数,int,SYMBOL,运算符,operator,重载
From: https://www.cnblogs.com/sisyphus-616/p/17776254.html

相关文章

  • Java语法之运算符二(附练习和答案)
    10.自增自减运算符分类:++自增运算符--自减运算符++:就是把变量里面的值+1--:就是把变量里面的值-1使用方式:放在变量的前面,我们叫做先++。比如:++a放在变量的后面,我们叫做后++。比如:a++注意点:不管是先++,还是后++。单独写在一行的时候,运算结果是一模一样的。案例://++inta=10;......
  • C++零基础教程(函数重载)
    (文章目录)前言本篇文章来讲解函数重载,函数重载在C++中是非常重要的一个概念。一、概念讲解C++中的函数重载是指在同一个作用域中定义多个具有相同名称但参数列表不同的函数。函数重载允许使用相同的函数名来表示执行类似但具有不同参数类型或参数数量的操作。这样做可以提高......
  • 运算符
    运算符算数运算符操作符描述例子+加法-相加运算符两侧的值A+B等于30-减法-左操作数减去右操作数A–B等于-10*乘法-相乘操作符两侧的值A*B等于200/除法-左操作数除以右操作数B/A等于2%取余-左操作数除以右操作数的余数B%A等......
  • 重写和重载
    2023.10.181.classA{publicAfoo(){returnthis;}}classBextendsA{publicAfoo(){returnthis;}}classCextendsB{_______}可以填入哪个而不报错Apublicvoidfoo(){}Bpublicintfoo(){return1;}Cpubli......
  • 运算符 列名*1.1 case when... then ..when.. then ..else.. end
    selectENAMEas'姓名',SALas'原始工资',(SAL*1.1)as'涨工资10%'fromempwherejob='MANAGER';  #经理涨薪%10,销售涨薪%50其余不变需要使用casewhenthenwhenthenelseendselectename,job,salas'原来的薪水'......
  • 前端打怪之旅=>Es6入门(运算符、Symbol)
    运算符...扩展运算符能将数组转换为逗号分隔的参数序列声明一个数组consttfboys=['易烊千玺','王源','王俊凯'];//声明一个函数functionaction(){console.log(arguments)}action(tfboys) 是一个数组元素,arguments里......
  • 无涯教程-NumPy - 右移运算符函数
    numpy.right_shift()函数将数组元素的二进制表示形式向右移动指定的位置,并在左侧添加相等数量的0。importnumpyasnpprint'Rightshift40bytwopositions:'printnp.right_shift(40,2)print'\n'print'Binaryrepresentationof40:'printnp.binary_repr(......
  • 无涯教程-NumPy - 左移运算符函数
    numpy.left_shift()函数将数组元素的二进制向左移动指定位置,从右边追加等号0。importnumpyasnpprint'Leftshiftof10bytwopositions:'printnp.left_shift(10,2)print'\n'print'Binaryrepresentationof10:'printnp.binary_repr(10,width=......
  • 无涯教程-NumPy - 按位运算符
    以下是NumPy包中可用的按位运算功能。Sr.No.描述1bitwise_and计算数组元素的按位与运算2bitwise_or计算数组元素的按位或运算3invert按位计算NOT4left_shift将二进制表示形式的位向左移动5right_shift将二进制表示形式的位向右移参考链接https://ww......
  • 2023_10_15_DAY_01_JAVA_SE_Java基础知识_中_变量与运算符
    2023_10_15_DAY_01_JAVA_SE_Java基础知识_中_变量与运算符标识符、关键字和保留字标识符在Java语言中,通过标识符来表示一些元素的名字,比如变量名、类名、方法名和包名等。Java中的标识符要符合下面的规则:标识符必须以字母、下划线(_)、数字或美元($)组成;标识符必须由字母、下......