C++ 传递机制,自己总结(平台VS2010)

来源:互联网 发布:原始杀戮优化 编辑:程序博客网 时间:2024/03/29 07:33

1.函数调用:

栈指针esp,帧指针ebp

        函数调用过程:

push 参数2push 参数1call fun ;将下一条地址压栈push ebpmov ebp,esp         
函数返回过程:

mov eax,[ebp-0x04]  ;返回值 放在eax中leaveret

2.返回引用,与按值返回

不要返回局部变量的引用:

int& fun(){int a=100;return a;}void m_test(){int a,b,c,d,e,f;a=4;b=1;c=2;d=5;e=6;f=7;}int main(){int& c=fun();//如果是int c=fun();这个地方已经将100拷贝到了c中,后面没有大问题,因为类型是int,如果是自定义类,会有大问题cout<<"C before call m_test():"<<c<<endl;m_test();cout<<"C after call m_test():"<<c<<endl;}Result:C before call m_test():100C after call m_test():4

自定义类返回过程:

class ClassA{public:ClassA(int pa=1){a=pa;cout<<"Construct"<<endl;};ClassA(ClassA& p){a=p.a;cout<<"copy"<<endl;}ClassA& operator =(ClassA &p){a=p.a;cout<<"operator ="<<endl;return *this;}~ClassA(){a=0;cout<<"Destroy"<<endl;}int a;};ClassA fun(){ClassA x(2);return x;}
下面讨论三个main函数:

case1:

int main(){ClassA& b=fun();cout<<b.a<<endl;return 0;}Result:Construct  ---1 copy       ---2Destroy    ---32          ---4Destroy    ---5
分析:

---1:局部变量 x 的定义,调用构造。

---2:fun函数返回前,将 x 拷贝到 ”临时对象“

---3:fun函数返回前,拷贝构造 ”临时对象“ 完成后,将局部变量(对象)x 销毁 即调用析构函数。返回后,ClassA的引用B同样指向 ”临时变量“

---4:输出b.a。

---5:销毁b。

注:由ClassA()调用而生成的临时对象却并不会在 表达式:ClassA& b=fun(); 结束之后立即被销毁,这个临时对象将会被引用到b上,在b的生命周期结束时,这个临时对象才被销毁。


case2:

int main(){ClassA* b=&fun();cout<<b->a<<endl;return 0;}Result:Construct   ---1copy        ---2Destroy     ---3Destroy     ---40           ---5

分析:

---1:局部变量 x 的定义,调用构造。

---2:fun函数返回前,将 x 拷贝到 ”临时对象“。

---3:fun函数返回前,拷贝构造 ”临时对象“ 完成后,将局部变量(对象)x 销毁 即调用析构函数。

---4:返回后,将”临时变量“地址赋给ClassA的指针b。在表达式执行完成后,临时对象将被销毁,即调用析构函数。而b指向销毁的对象。

---5:因为b指向调用过析构函数的的对象,因此b->a的值为0。

注:如果不是保留临时对象的引用,而是保存了临时对象的地址,则不会有引用返回的特性,临时对象依然会在表达式结束后,马上自动销毁


case 3:

int main(){ClassA b=fun();cout<<b.a<<endl;return 0;}Result:Construct   ---1copy        ---2Destroy     ---32           ---4Destroy     ---5

分析:

---1:局部变量 x 的定义,调用构造。

---2:fun函数返回前,将 x 拷贝到 隐式“传”过来的参数:b对象中。

---3:fun函数返回前,拷贝构造完成后,将局部变量(对象)x 销毁 即调用析构函数。

---4:输出b.a(返回后不做与对象b相关的任何事)。

---5:销毁b。

注:case3与case1的区别在于,case3执行函数前,已经为对象b分配了存储空间,在fun返回时并没有生成“临时对象”,在这一点上,自定义类与基本类型变量有区别。


case 4:

int main(){  ClassA b;b=fun();  cout<<b.a<<endl;  return 0;  }  Result:Construct   ---1Construct   ---2copy        ---3Destroy     ---4operator =  ---5Destroy     ---62           ---7Destroy     ---8

分析:

---1:main中,对象b的定义

---2:局部变量 x 的定义,调用构造。

---3:fun函数返回前,将 x 拷贝到 ”临时对象“。

---4:fun函数返回前,拷贝构造 ”临时对象“ 完成后,将局部变量(对象)x 销毁 即调用析构函数。

---5:完成b=临时变量 的赋值运算符重载 操作。

---6:临时变量销毁,调用析构。

---7:输出b.a。

---8:销毁b。





        

原创粉丝点击