Chinaunix首页 | 论坛 | 博客
  • 博客访问: 78145
  • 博文数量: 6
  • 博客积分: 1402
  • 博客等级: 上尉
  • 技术积分: 270
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-04 23:37
文章分类
文章存档

2011年(1)

2008年(5)

我的朋友
最近访客

分类: C/C++

2008-03-24 19:20:48

class A
{
         int i;
         int j;

public:
         A(const A& a)
                   :i(a.i), j(a.j) {}

         A(int ii=0, int jj=0)
                   : i(ii), j(jj) {}
};
 

A func()
{
         return A(2,3);
}

 
int main()

{
         A a(1,2);

         A b = func();

         return 0}


成员函数的this指针是通过ecx传递参数的,而不是压在栈里;作为一类特殊的成员函数,构造函数还会通过eax返回this指针

对于func()这种按值返回对象的函数,编译器会把接收返回对象的“待创建对象(即main中的b)”的指针作为隐藏参数,这是通过传统的压栈传参方式实现的;这样做的目的是要在func内部直接构造待创建对象,这是通过把隐藏参数放到ecx里作为构造函数的this指针来实现的;func返回之后,由于b已经构造好了,所以本条语句执行完毕,main函数只需要根据_cdecl规定add esp,4来恢复栈指针即可(由于之前压入了隐藏参数)

func调用A的构造函数时,还有一点细微差别,如果按原码所示,即:

A func()

{

         return A(2,3);

}

此时,func会直接调用A的普通构造函数,并把隐藏参数赋给ecx,这样构造函数的this指针指向待创建对象

如果换一种func的写法如下:

A func()

{

         A temp(2,3);

         return temp;

}

此时,func会先在自己的栈桢里用普通构造函数构造一个temp对象,然后再调用A的拷贝构造函数来构造待创建对象。具体来说,它会把temp的地址压栈作为拷贝构造函数的参数(const A& a),然后把隐藏参数赋给ecxthis指针

 

 

有一种和上面代码相似的常见错误编码方式,所示如下:

const A& func()

{

         A temp(2,3);

         return temp;

         //return A(4,5);

}

它企图通过const A&来返回一个创建在栈里的对象。此时构造函数并不在func内被调用,而是func确实通过eax返回了自己栈桢内的临时对象的地址,然后由main函数来调用A的拷贝构造函数。可想而知,由于拷贝构造函数会往栈里写参数,所以之前的临时对象在拷贝之前就已经被破坏了。注意,当以const A&方式返回时,return A(4,5);A temp(2,3); return temp;是完全一样的,都会调用两次构造函数,一次由func调用普通构造函数创建temp,一次由main调用拷贝构造函数来创建b
阅读(1269) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~