Code Bye

关于拷贝构造函数的一个问题

#include<iostream>
using namespace std;
class Point
{
	public:
	Point(int a0, int b = 0);
	Point(const Point &p);
	void print()
	{
		cout<<x<<" "<<y<<endl;
	}
	private:
	int x, y;
};
Point::Point(int a, int b)
{
	x = a;
	y = b;
	cout<<"Using normal constructor\n";
}
Point::Point(const Point &p)
{
	x = 2 * p.x;
	y = 2 * p.y;
	cout<<"Using copy constructor\n";
}
void fun1(Point p)
{
	p.print();
}
Point fun2()
{
	Point p4(10,30);
	return p4;
}
int main()
{
	Point p1(30,40);
	p1.print();
	Point p2(p1);

	p2.print();
	Point p3 = p1;

	p3.print();
	fun1(p1);
	p2 = fun2();

	p2.print();
	return 0;

}


本人不太理解输出结果最后一行  为什么会输出20 和 60

解决方案

5

打印不是很清楚么?
Point p4(10,30); //一般构造
然后返回p4拷贝构造临时变量,调用拷贝构造函数,就各乘以2了;假如开启了优化,此步可能会被优化掉。
最后临时变量拷贝赋值给p2,调用的是operator =,但你没有重载,所以没打印输出。

10

返回值优化(Return Value Optimization,简称RVO),是这么一种优化机制:当函数需要返回一个对象的时候,假如本人创建一个临时对象用户返回,那么这个临时对象会消 耗一个构造函数(Constructor)的调用、一个复制构造函数的调用(Copy Constructor)以及一个析构函数(Destructor)的调用的代价。
你假如是VS的话:DEBUG和RELEASE模式能很清楚的看到,假如是GCC编译器,可能编译器本人进行了RVO优化,看不到区别

5

p2 = fun2();//fun2中构造了(10,30)的对象,在return时调用了拷贝构造,于是成了(20,60)

5

很明显,在题主是在windows环境下运行的这段代码,假如要是使用gcc的话你会发现有多处了一个“Using normal constructor”输出,其中原因,3楼已经给出了完整的解释。
对于题主的问题。
关键是下面两条语句:
p2 = fun2();
p2.print();
执行赋值符号右侧的fun2();时
Point fun2()
{
Point p4(10,30);
return p4;
}
调用了通用构造函数构造出p4. x、y分别是10 和 30。
当执行赋值符号时,p2 = fun2();会调用拷贝构造函数。拷贝构造函数需要将x、y都乘以2,所以输出结果变成了20和60.这个拷贝构造函数的调用是由赋值符号引起的。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于拷贝构造函数的一个问题