Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1676304
  • 博文数量: 311
  • 博客积分: 7778
  • 博客等级: 少将
  • 技术积分: 4186
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 19:59
个人简介

蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88

文章存档

2012年(3)

2011年(115)

2010年(170)

2009年(23)

分类: C/C++

2010-01-05 13:19:36

C++里都要求类都有拷贝构造函数.如果类里没有这个,编译器将会自动加入一个浅拷贝的构造函数.
一般文档会明确有三种地方会自动执行拷贝构造函数.
1.用一个对象初始化另外一个对象时.
  
2.对象作传值的函数形参时
 
3.函数返回值是对象(不是地址也不是引用)
 
其中前2种,基本没有什么问题,但是最后一种,在不同OS是有不同的表现.程参见下列程序.下列程序中,执行几次CDate类构造函数,其中哪一步是拷贝构造函数?
 
 

#include <stdio.h>

class CDate
{
public:
   CDate()
    {
        printf("Contrutor %x\n",this);
     }
     
   CDate(CDate &src)
    {
         printf("Copy Contrutor %x\n",this);
    }
    
    ~CDate()
    {
      printf("Destruator %x\n",this);
    }

    void print()
    {
     printf("print %x\n",this);
    }

};

CDate func(CDate src)
{
  CDate tmp(src);
  return tmp;
}


int main()
{
  CDate date;
  func(date).print();
  return 0;
}

 

在VC++ 6.0执行结果是

Contrutor 12ff70
Copy Contrutor 12ff08
Copy Contrutor 12feec
Copy Contrutor 12ff68
Destruator 12feec
Destruator 12ff08
print 12ff68
Destruator 12ff68
Destruator 12ff70
Press any key to continue

 

可以看到作了四次构造函数,其中有三次是拷贝构造函数.分别是CDate date做了一次默认构造函数(Contrutor 12ff70)

Date->src 做传值形参,这做一次拷贝构造src(Copy Contrutor 12ff08),

然后CDate tmp(src),这一次再做拷贝构造 tmp(Copy Contrutor 12feec)

然后最后 return tmp,在做了一次拷贝构造,创建一个中间对象(Copy Contrutor 12ff68
),而且可以看到 func().print(),用的正是0x12ff68,即中间对象.

这个完全合符C++的标准的。

但是在RHEL 5/gcc 4.12 编译后执行结果


Contrutor bfc37d0d
Copy Contrutor bfc37d0f
Copy Contrutor bfc37d0e
print bfc37d0e
Destruator bfc37d0e
Destruator bfc37d0f
Destruator bfc37d0d

可以看到拷贝构造和做传值形参是执行了拷贝构造函数。但是在return tmp;可以发现,没有执行拷贝构造。而且print  用的bfc37d0e,就是tmp本身。换句话说,g++对于返回对象,全部采用引用。而非采用拷贝构造函数。

结论:G++ 对于返回对象没有采用拷贝构造,而且采用引用。

阅读(1461) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~