运算符重载问题

时间:2022-09-10 17:34:46
类定义如下:
class rect
{
public:
    rect(int x=0):m(x){};
    rect(rect& r):m(r.m){};
    rect operator=(rect& r)
    {
        m=r.m;
        return *this;
    };
    rect operator+(rect &r)
    {
        rect ret(r.m+m);
        return ret;
    };    
private:
    int m;    
};


主程序如下:
#include"rect.h"
int main()
{
    rect r1(2);
    rect r2;
    rect r3;
    
    r2=r1;
    r3=r1+r2;//编译出错
}

我想请问:为什么r1+r2赋值给r3时会出错。如果我不重载=时,r3=r1+r2就不会报错,且结果也是正确。
如果我想在一个类中同时重载+和=运算符时,程序该怎么写?

12 个解决方案

#1


r3=(r1+r2)试试

#2


VC6.0 编译通过,运行正常。鉴定完毕

#3


rect operator=(const rect& r)
楼主operator=重载不符合常规。

#4


你的是什么编译器?
VC6是可以编译运行的

#5


operator=()的参数是rect&,而operator+()返回rect,是一个临时对象,临时对象不能绑定到非常量引用。
应该把operator=(rect& r)换成operator=(rect const& r)。
另外,应该按这种格式重载:
rect& operator=(rect const& r);
rect const operator+(rect const& r);

#6


operator =请传回一个reference而不是object,也就是说:rect& operator=(rect& r)

#7


rect const operator+(rect const& r);
应该是
rect const operator+(rect const& r) const;

#8


写错,应该是rect& operator=(const rect& r)

#9


标准问题
把头文件改成#include <iostream.h> 就没有错
而#include<iostream> 会出错

#10


标准问题
把头文件改成#include <iostream.h> 就没有错
而#include<iostream> 会出错
----------------------------------------
#include <iostream.h> 这个的效果和 

#include<iostream>
using namespace std;
这两句家在一起的效果基本是一样的
。。。

#11


多谢,受益非浅啊

#12


不知道你用的是什么编译器,你的程序在我的VC7.1上顺利编译链接成EXE,该程序运行良好,其中的重载运算符也正确无误。

  其实你的重载运算符不存在正确与不正确的问题:

在你的rect类中加入如下函数:

void show()
{
   cout << "rect.m: " << m << endl; 
}

再在你的main()函数中加入如下代码:

rect r1(2);
rect r2;
rect r3;

r1.show(); 
r2.show();
r3.show();//这三次调用show()演示结果是3个rect.m的初值分别是2、0、0! 

r2=r1;
r3=r1+r2;//并无编译出错

cout << endl;

r1.show(); 
r2.show();
r3.show();();//这三次调用show()演示结果是3个rect.m的初值分别是2、2、4! 

     演示上述代码,可以证明程序没有问题。但是,虽然我先前说过:"你的重载运算符不存在正确与不正确."的问题,却存在重载策略不佳的问题! 

     首先,对于你的rect类而言,根本不必重载'='运算符!因为这个类本身等同于一个C结构,其中并无继承关糸,当然也就不存在类体糸的某一部份还存在可能有的构造函数(除它自已有一个外),这样的类会被编译器打上"Plain Ol' Data"标记,这样的类具有‘Bitwise Copy Semantics'语意,于是编译器会对你的'r3=r1+r2;'作如下'手脚':

原码为:
         rectTemp = r1 + r2;//产生一个临时对象;
         r3.operator=(rectTemp);//调用你重载的'='运算符函数;
修改为:
         
        rectTemp = r1 + r2;//产生一个临时对象;
         r3.m = rectTemp.m;//Birwise Copy!免去调用函数的必要开销!

         伴随你的'='赋值代码的调用次数,修改后的代码将有明显的效率提升!所以对于类似rect的类,请大家不必为它重载赋值运算,同理也不必为它写一个考贝构造函数!因此rect类修改如下:

class rect
{
public:
    rect(int x=0):m(x){};
    
    rect operator+(rect &r)
    {
        rect ret(r.m+m);
        return ret;
    };    
private:
    int m;    
};//代码精简,同时提升编译和程序执行效率!

     



#1


r3=(r1+r2)试试

#2


VC6.0 编译通过,运行正常。鉴定完毕

#3


rect operator=(const rect& r)
楼主operator=重载不符合常规。

#4


你的是什么编译器?
VC6是可以编译运行的

#5


operator=()的参数是rect&,而operator+()返回rect,是一个临时对象,临时对象不能绑定到非常量引用。
应该把operator=(rect& r)换成operator=(rect const& r)。
另外,应该按这种格式重载:
rect& operator=(rect const& r);
rect const operator+(rect const& r);

#6


operator =请传回一个reference而不是object,也就是说:rect& operator=(rect& r)

#7


rect const operator+(rect const& r);
应该是
rect const operator+(rect const& r) const;

#8


写错,应该是rect& operator=(const rect& r)

#9


标准问题
把头文件改成#include <iostream.h> 就没有错
而#include<iostream> 会出错

#10


标准问题
把头文件改成#include <iostream.h> 就没有错
而#include<iostream> 会出错
----------------------------------------
#include <iostream.h> 这个的效果和 

#include<iostream>
using namespace std;
这两句家在一起的效果基本是一样的
。。。

#11


多谢,受益非浅啊

#12


不知道你用的是什么编译器,你的程序在我的VC7.1上顺利编译链接成EXE,该程序运行良好,其中的重载运算符也正确无误。

  其实你的重载运算符不存在正确与不正确的问题:

在你的rect类中加入如下函数:

void show()
{
   cout << "rect.m: " << m << endl; 
}

再在你的main()函数中加入如下代码:

rect r1(2);
rect r2;
rect r3;

r1.show(); 
r2.show();
r3.show();//这三次调用show()演示结果是3个rect.m的初值分别是2、0、0! 

r2=r1;
r3=r1+r2;//并无编译出错

cout << endl;

r1.show(); 
r2.show();
r3.show();();//这三次调用show()演示结果是3个rect.m的初值分别是2、2、4! 

     演示上述代码,可以证明程序没有问题。但是,虽然我先前说过:"你的重载运算符不存在正确与不正确."的问题,却存在重载策略不佳的问题! 

     首先,对于你的rect类而言,根本不必重载'='运算符!因为这个类本身等同于一个C结构,其中并无继承关糸,当然也就不存在类体糸的某一部份还存在可能有的构造函数(除它自已有一个外),这样的类会被编译器打上"Plain Ol' Data"标记,这样的类具有‘Bitwise Copy Semantics'语意,于是编译器会对你的'r3=r1+r2;'作如下'手脚':

原码为:
         rectTemp = r1 + r2;//产生一个临时对象;
         r3.operator=(rectTemp);//调用你重载的'='运算符函数;
修改为:
         
        rectTemp = r1 + r2;//产生一个临时对象;
         r3.m = rectTemp.m;//Birwise Copy!免去调用函数的必要开销!

         伴随你的'='赋值代码的调用次数,修改后的代码将有明显的效率提升!所以对于类似rect的类,请大家不必为它重载赋值运算,同理也不必为它写一个考贝构造函数!因此rect类修改如下:

class rect
{
public:
    rect(int x=0):m(x){};
    
    rect operator+(rect &r)
    {
        rect ret(r.m+m);
        return ret;
    };    
private:
    int m;    
};//代码精简,同时提升编译和程序执行效率!