所在的位置: C++ >> C++市场 >> C编程语言C运算符重载

C编程语言C运算符重载

北京治疗白癜风总共要多少钱 https://m-mip.39.net/baidianfeng/mipso_4513569.html

1.加号运算符重载

  运算符重载概念:对已有的运算符进行定义,赋予另外一种功能,以适应不同的数据类型。运算符重载,也可以发生函数重载。

classPerson{public:intm_A;intm_B;PersonPersonAdd(Personp){Persontemp;temp,m_A=this.m_A+p.m_A;temp,m_B=this.m_B+p.m_B;}//1.成员函数重载+号Personoperator+(Personp){Persontemp;temp,m_A=this.m_A+p.m_A;temp,m_B=this.m_B+p.m_B;}};//2.全局函数重载+号Personoperator+(Personp1,Personp2){Persontemp;temp,m_A=p1.m_A+p2.m_A;temp,m_B=p1.m_B+p2.m_B;}voidtest01(){Personp1;p1.m_A=10;p1.m_B=10;Personp2;P2.m_A=10;p2.m_B=10;Personp=p1.PersonAdd(p2);//这个可以实现成员函数的相加。//但是系统提供一个专门重载+号的函数名operator+这样可以实现简化//1.成员函数重载+号Personp=p1.operator+(p2);//可以简化为Personp=p1+p2;//2.全局函数重载+号Personp=operator+(p1.p2);//可以简化为Personp=p1+p2;//运算符重载,也可以发生函数重载。}

总结:

    1.对于内置的数据类型的表达式的运算符是不可以改变的

    2.不要滥用运算符重载

2.左移运算符重载

    作用:可以输出自定义数据类型。

问题:

inta=10;coutaendl;//可以输出classPerson{public:intm_A;intm_B;};Personp;p.m_A=10;P.m_B=20;coutpendl;//无法输出//这个是就可以从在左移运算符让它输出自定义的数据类型。

解答

classPerson{public:intm_A;intm_B;//利用成员函数重载左移运算符是无法实现的只能使用全局函数重载左移运算符voidoperator(){}};//利用全局函数重载左移运算符ostreamoperator(ostreamcout,Personp){//本质operator(cout,p)简化coutpcoutp.m_Ap.m_B;returncout;}voidtest01(){Personp;p.m_A=10;p.m_B=20;coutpendl;//报错无法直接输出p//当使用全局函数重载左移运算符后coutpendl;//可以输出了}.递增运算符重载

作用:通过重载递增运算符,实现自己定义整型数据的输出

问题:

inta=10;a++;++a;//可以直接输出classMyInteger{private:intm_Num;public:MyInteger(){m_Num=0;}}MyIntegermyint;//重载递增运算符实现:myint++;++myint;

解决:

classMyInteger{//定义operator为友元friend:ostreamoperator(ostreamcout,MyIntegermyint);private:intm_Num;public:MyInteger(){m_Num=0;}//重载前置++运算符MyIntegeroperator++(){//返回值为引用,为了一直对一个数据进行递增操作m_Num++;return*this;}//重载后置++运算符MyIntegeroperator++(int){//这个int代表占位参数,可以用于区分前置++和后置++MyIntegertemp=*this;m_Num++;returntemp;//temp为局部变量,程序结束就会释放,所以返回值不能是引用。}}//利用全局函数重载左移运算符ostreamoperator(ostreamcout,MyIntegermyint){//本质operator(cout,p)简化coutpcoutmyint.m_Num;//因为m_Num是私有属性,需要给该全局函数加上友元returncout;}voidtest01(){MyIntegermyint;coutmyintendl;//报错,需要重载左移运算符cout++myintendl;//报错,当前运行自增运算需要重载递增运算符//在重新定义递增运算符后cout++myintendl;//可以运行coutmyint++endl;}4.赋值运算符重载

    C++编译器至少给一个类添加4个函数(原先是说个函数)

      1.默认的构造函数(无参,函数体为空)

      2.默认的析构函数(无参,函数体为空)

      .默认拷贝构造函数,对属性进行值拷贝。

      4.赋值运算符operator=,对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作也会出现深浅拷贝问题。

classPerson(){public:int*m_Age;Person(intage){//把数据存放到堆区m_Age=newint(age);}~Person(){//释放堆区数据if(m_Age!=null){deletem_Age;m_Age=null;}Personoperator=(Personp){if(m_Age!=null){//先把p2堆区数据释放干净在进行赋值操作。deletem_Age;m_Age=null;}//深拷贝m_Age=newint(*p.m_Age);return*this;}}}voidtest01(){Personp1(10);Personp2(18);Personp(16);cout"p1的年龄:"*p1.m_Ageendl;//输出:p1的年龄:10cout"p2的年龄:"*p2.m_Ageendl;//输出:p0的年龄:18p2=p1;//赋值操作如果不定义析构函数,进行堆区数据的释放就不会进行报错,如果一旦定义了系统就会报错。报错原因和深浅拷贝出错的原因一致,都是因为p1,p2都指向同一堆区数据,其中p1或p2一旦有一方进行堆区数据的释放,另一方就会出错。//解决方法:重载赋值运算符,让两者的数据分别写到堆区。//重写赋值操作后p2=p1=p;//正常运行}5.关系运算符重载

  作用:重载关系运算符,可以让两个自定义类型对象进行对比操作。

//重载关系运算符classPerson{public:intm_Age;stringm_Name;Person(stringname.intage){m_Name=name;m_Age=age;}booloperator==(Personp){if(this.m_Name==p.m_Namethis.m_Age==p.m_Age){returntrue;}returnfalse;}};voidtest01(){Personp1("tom",18);Personp2("tom",18);if(p1==p2){//报错p1==p2系统无法识别,需要重载,重载后就可以使用cout"p1和p2相等"endl;}}6.函数调用运算符重载

    1.函数调用运算符()也可以重载

    2.由于重载后使用方式非常想函数的调用,因此称为仿函数

    .仿函数没有固定写法,非常灵活

classMyPrint{public://重载函数调用运算符voidoperator()(stringtest){couttestendl;}};//正常的函数voidMyPrint02(stringtest){couttestendl;}voidtest01(){MyPrintmyPrint();//重载函数调用运算符,之后的调用myPrint("helloword");//由于使用起来非常类似于函数调用,因此称为仿函数//正常函数调用MyPrint02("helloword");}




转载请注明:http://www.aierlanlan.com/rzdk/5707.html