c++ =号重载及函数返回值临时变量问题

      今天写c++操作符重载发现了一些问题,遂向师兄请教,于是引出一堆问题,讨论过程中,也解了我几个大疑惑。

      首先写一个c++类,如果你不显示实现,c++会帮你实现拷贝,=号重载,无参默认构造函数等三个基本成员函数。

     感觉上拷贝和=号重载其实是一个意思,但是编译器不这么干,这两个是分别实现的。

     无参构造函数是其成员各自调用自己的无参构造函数,如此循环调用下去。

     关于c++的临时变量,这个很诡异,函数的返回值,写过汇编程序的人知道,函数其实就是一个小程序段,被调用的时候先把参数压入栈,接着把返回地址压入栈,函数调用完返回的时候,直接ret,IP=返回地址,继续执行下一条指令(这里面记不太清了,大概是这么个意思),但是函数返回值在哪?木有啊,ret只是把CS:IP恢复位置,返回值存在哪?答案是栈中,有返回值c++创建了一个临时变量存储这个返回值,因为这个临时变量是在运行时创建的,所以只能在栈中。如果想取这个临时变量的引用,那么前面必须加const,不然会报错,但是如果取这个临时变量的地址的话,不用加const,编译器仅仅会报一个警告,所以我们可以修改临时变量,临时变量的作用域(这个很危险,因为这个地址可能存放其他重要东西)。临时变量在栈中会随时被覆盖,不安全。话不多说,上代码:

#include <iostream>
using namespace std;
int x=0;

class Sales_item{
public:
string name;
float  price;
public:

Sales_item(string name,float price){
this->name=name;
this->price=price;
}
Sales_item& operator =(const Sales_item &a){
cout<<"x="<<x<<endl;
cout<<"left= addresss:"<<this<<",=right address:"<<&a<<endl;
x+=1;
return (*this);
}

Sales_item():name(""),price(0){}
Sales_item operator +(const Sales_item &a){
 Sales_item result;
result=a;
result.name+=" "+a.name;
result.price+=a.price;
return result;
}
friend istream& operator >>(istream &is,Sales_item &sales);
friend ostream& operator <<(ostream &os,const Sales_item &sales);
//friend Sales_item operator +(const Sales_item &a,const Sales_item &b);
};
Sales_item global_test("test2",13);
int main(void){
Sales_item test(global_test);

//test+global_test;
Sales_item* result1=&(test+global_test);

cout<<"1:wuming:"<<(*result1)<<endl;
//cout<<"name address:"<<&(result1->name)<<",price address:"<<&(result1->price)<<endl;
cout<<"2:wuming:"<<(*result1)<<endl;
cout<<"name address:"<<&(result1->name)<<",price address:"<<&(result1->price)<<endl;
result1->name="modify";
cout<<"3:wuming:"<<(*result1)<<endl;
cout<<"name address:"<<&(result1->name)<<",price address:"<<&(result1->price);


/*注释块一
Sales_item sales_0;
sales_0=test+global_test;
cout<<"sales_0 address:"<<&sales_0;
*/
/*注释块二
Sales_item sales=test+global_test;
cout<<"sales address:"<<&sales;
*/


return 0;
}
istream& operator >>(istream &is,Sales_item &sales){
is>>sales.name>>sales.price;
return is;
}
ostream& operator <<(ostream &os,const Sales_item &sales){
os<<sales.name<<" "<<sales.price;
return os;
}

上面就是代码编译运行的结果,看到了吧,临时变量不可靠,连着输出两次就出错了,值被覆盖了,所以第一个name字段就读不出来了,临时变量取地址会报警告,如果取引用的话前面不加const会报错。

如果把注释块一注释去掉,同时把上面指针那一块注释掉,看结果:

执行了2次=号重载操作,第一次把返回值拷贝到临时变量(无名),第二次把临时变量拷贝到sales_0。

接下来把注释块一注释掉,去掉注释二,看结果:

可以看到这个只执行了一次拷贝操作,具体原因不知道,猜测可能是编译器的优化吧。

先写这么多了,c++是个大坑呀,果断学汇编呀,学好了汇编编译下应该更能看出来编译器工作原理。

posted @ 2012-10-30 22:44  huals  阅读(1139)  评论(0编辑  收藏  举报