Chinaunix首页 | 论坛 | 博客
  • 博客访问: 988590
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-23 16:36:40

#include <iostream>
using namespace std;

struct A
{
    A() 
{ cout << "A()" << endl; }
    
//A( const A& ) { cout << "A(A)" << endl ;}
    A& operator=const A&  ) { cout << "A=A" << endl; }
    
~A() { cout << "~A()" << endl; }
}
;

A foo( A a )
{
    cout 
<< "---" << endl;
    
return a;
}


int main(void)
{
    
{
        foo( A() );
    }


    system( 
"pause" );
    
return 0 ;
}


在 VC++2005 下输出为:
A()
---
~A()
~A()
~A()

为什么 return a; 会调用2次析构函数?


---------------------------------- 简化一下----------------------------------
#include
using namespace std;

struct A
{
    A() { cout << "A()" << endl; }
    //A( const A& ) { cout << "A(A)" << endl ;}
    A& operator=( const A&  ) { cout << "A=A" << endl; }
    ~A() { cout << "~A()" << endl; }
};

void foo( A a )
{
}

int main(void)
{
    {
        foo( A() );
    }

    system( "pause" );
    return 0 ;
}

VS2005中的怪异现象描述:

如果没有 A( const A& ) { cout << "A(A)" << endl ;}
那么输出
A()
~A()
~A()

如果加上 A( const A& ) { cout << "A(A)" << endl ;}
那么输出
A()
~A()
阅读(3251) | 评论(20) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-23 16:39:29

hpho
1,凭什么说"拷贝构造函数会默认生成"?! 若你说根据标准那请把相关章节内容列出来.不然编绎器所生成的"位拷贝构造"可能根本只是在调用函数里插入memcpy罢了.

2,本来提供自己的拷贝构造和不提供其语义区别是: "是否为拷贝时的构造行为负责."因此它们在类设计上行为本质就是不一致的.而且这里主要是牵涉临时对象的问题.若
A* p;
foo(*(p=&A())); //这里无论是否有拷贝构造都一样

网友评论2012-11-23 16:39:21

周星星
为什么不算?
根据C++标准,拷贝构造函数会默认生成,因此两段代码行为应当一致。
即使考虑到“在‘用户感知行为一致’下,编译器可随意调整代码”,那现在行为不一致。
再拉上“代码优化”,编译器默认生成的无输入输出的拷贝构造函数 现在比……更差了。

网友评论2012-11-23 16:39:14

hpho
不算.

网友评论2012-11-23 16:39:06

周星星
根据你的代码,是不是这样:
无拷贝构造版本:
A() @ 1
//A(A) @ 2
---
foo::parameter::a @ 2
//A(A) @ 3
~A() @ 2
foo::return::A @ 3
~A() @ 3
~A() @ 1

有拷贝构造版本:
A() @ 1
---
foo::parameter::a @ 1
A(A) @ 2
~A() @ 1
foo::return::A @ 2
~A() @ 2

那这算不算VC2005的bug?

网友评论2012-11-23 16:38:55

hpho
#define COPY_CONSTRUCT 1

template<int i>
struct A;

template<>
struct A<!COPY_CONSTRUCT>
{
    A() { printf("A() @ %p\n",this); }
//  A( const A& ) { printf("A(A) @ %p\n", this);}
    A& operator=( const A&  ) { cout << "A=A" << endl; }
    ~A() { printf("~A() @ %p\n"