一道笔试题的解读?求讨论~

铭毅天下
大数据领域优质创作者
博客专家认证
2012-09-18 07:18:41
//应该如何解读?

class A
{
static int objectCount;
public:
A()
{
objectCount++;
cout << "A():" << objectCount << endl;
}

A(const A& r)
{
objectCount++;
cout << "A(const A& r):" << objectCount << endl;
}

~A()
{
objectCount--;
cout << "~A():" << objectCount << endl;
}
};

int A::objectCount = 0;

A f(A x) //调用默认拷贝构造函数 A(const A& r):2
{
cout << endl << "Begin: f(A x)" << endl;
return x;
} //~A():1

int main()
{
A h; //A():1
A h2 = f(h); //调用默认拷贝构造函数A(const A& r):2
cout << endl << "End(main): f(A x)" << endl << endl;

return 0;
} //~A():1 析构h
//~A():0 构函h2

疑问:考虑到临时对象的生成,并且A h2=f(h)是初始化而非赋值,
实际执行的结果为:
A():1
A(const A& r):2
Begin: f(A x)
A(const A& r):3
~A():2
End(main): f(A x)
~A():1
~A():0
对A f(A x)的调用不大理解,求解释讨论(注释部分是我理解的,与实际结果不一致),谢谢!
...全文
236 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
引用 8 楼 的回复:

C/C++ code
class A
{
static int objectCount;
public:
A()
{
objectCount++;
cout << "A():" << objectCount << endl;
}

A(c……

/函数里,一共产生了两个临时对象,一个是形参的副本,一个是返回值的副本 是对的。
从上面几楼加上……
[/Quote]
你可以在类里加个int变量,看看h2是否构造了。。。
Flammable_ice 2012-09-20
  • 打赏
  • 举报
回复
难道说产生的两次临时对象被一次析构掉了?我在思考这个问题。。
Flammable_ice 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
引用 8 楼 的回复:

C/C++ code
class A
{
static int objectCount;
public:
A()
{
objectCount++;
cout << "A():" << objectCount << endl;
}

A(c……

/函数里,一共产生了两个临时对象,一个是形参的副本,一个是返回值的副本 是对的。
从上面几楼加上……
[/Quote]
楼主,试想,如果是产生了两个临时对象,临时对象在用完后应该马上被析构才对的。End(main): f(A x)
在这句之前就应该执行两次析构函数,而不是一次哦。
铭毅天下 2012-09-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

C/C++ code
class A
{
static int objectCount;
public:
A()
{
objectCount++;
cout << "A():" << objectCount << endl;
}

A(c……
[/Quote]
/函数里,一共产生了两个临时对象,一个是形参的副本,一个是返回值的副本 是对的。
从上面几楼加上自己的理解,返回值的副本的副本即完成了h2的拷贝构造。
铭毅天下 2012-09-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

"赋值即拷贝"!
[/Quote]

醍醐灌顶a !谢谢!
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;

class A
{
static int objectCount;
public:
A()
{
objectCount++;
cout << "A():" << objectCount << endl;
}

A(const A& r)
{
objectCount++;
cout << "A(const A& r):" << objectCount << endl;
}

~A()
{
objectCount--;
cout << "~A():" << objectCount << endl;
}
};

int A::objectCount = 0;

A f(A x)
{
cout << endl << "Begin: f(A x)" << endl;
return x;
}

int main()
{
A h; //默认构造函数
A h2 = f(h); //函数里,一共产生了两个临时对象,一个是形参的副本,一个是返回值的副本,h2未被构造
cout << endl << "End(main): f(A x)" << endl << endl;

return 0;
}

  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
引用 3 楼 的回复:
对吗?
这句是:~A():1 //析构对象h2吗? h2只是完成了初始化并没有明确调用构造函数啊?
还是此处析构的是A(const A& r):2 拷贝构造的传递的实参的副本呢?

对的。
是析构h2对象哦。h2对象调用复制构造函数啊,复制构造函数也是构造函数的一种哦。
析构的就是h2对象。
[/Quote]
我不认为h2被构造了
ying0620 2012-09-19
  • 打赏
  • 举报
回复
"赋值即拷贝"!
Flammable_ice 2012-09-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
对吗?
这句是:~A():1 //析构对象h2吗? h2只是完成了初始化并没有明确调用构造函数啊?
还是此处析构的是A(const A& r):2 拷贝构造的传递的实参的副本呢?
[/Quote]
对的。
是析构h2对象哦。h2对象调用复制构造函数啊,复制构造函数也是构造函数的一种哦。
析构的就是h2对象。
miliggate 2012-09-18
  • 打赏
  • 举报
回复
把A传递进函数以后是一次Copy,然后析构他,但是返回时也要一份副本,所以就在Copy一次
也就是进去以后Object的值就没有便(加1又减去1)
铭毅天下 2012-09-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
你是这句话没看懂吧?A h2 = f(h);
在《C++PRIMER》中复制构造函数那章电子PDF版的407页(原书477-478页)中有这么一段话。
2,形参与返回值。
当形参为非引用类型的时候,将复制形参的值。类似地以非引用类型作为返回值时,将返回return语句中的值的副本。
所以f(h)是非引用的参数传……
[/Quote]

谢谢你的解释,正解应该如下吧:
A():1 //A h调用构造函数
A(const A& r):2 //实参传递时,复制实参的副本,调用拷贝构造函数
Begin: f(A x)
A(const A& r):3 //返回时,返回语句中x的副本,
~A():2 //返回时,临时对象在用完后马上被析构掉,要调用析构函数。与A(const A& r):3对应
End(main): f(A x)
~A():1 //析构对象h2
~A():0 //析构对象h
对吗?
这句是:~A():1 //析构对象h2吗? h2只是完成了初始化并没有明确调用构造函数啊?
还是此处析构的是A(const A& r):2 拷贝构造的传递的实参的副本呢?
Flammable_ice 2012-09-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
对A f(A x)的调用不大理解,求解释讨论
[/Quote]
你是这句话没看懂吧?A h2 = f(h);
在《C++PRIMER》中复制构造函数那章电子PDF版的407页(原书477-478页)中有这么一段话。
2,形参与返回值。
当形参为非引用类型的时候,将复制形参的值。类似地以非引用类型作为返回值时,将返回return语句中的值的副本。
所以f(h)是非引用的参数传递,而 f(h)的返回值作为一个临时对象,将这个临时对象初始化给h2,那么这时候还要再次调用复制构造函数。 临时对象在用完后马上被析构掉了,所以要调用析构函数。

铭毅天下 2012-09-18
  • 打赏
  • 举报
回复
我查了《Effiective C++》86页,函数参数都是以实际实参的复件(副本)为初值,而调用端所获得的也是函数返回值的一个复件(副本)。这些副本都是由对象的copy构造函数产生,这可能使得pass-by-value成为昂贵的(费事的)操作。

64,266

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧