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

1.函数调用:

栈指针esp,帧指针ebp

        函数调用过程:

push 参数2
push 参数1
call fun ;将下一条地址压栈

push ebp
mov ebp,esp
         
函数返回过程:

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

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():100
C 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       ---2
Destroy    ---3
2          ---4
Destroy    ---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   ---1
copy        ---2
Destroy     ---3
Destroy     ---4
0           ---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   ---1
copy        ---2
Destroy     ---3
2           ---4
Destroy     ---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   ---1
Construct   ---2
copy        ---3
Destroy     ---4
operator =  ---5
Destroy     ---6
2           ---7
Destroy     ---8

分析:

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

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

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

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

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

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

---7:输出b.a。

---8:销毁b。





        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值