复制构造函数必须定义为const形参的情况

以下代码拷贝构造函数的形参必须为const 引用类型。

测试代码:

#include <iostream>
using namespace std;
class cat
{
public:
	cat(int intialAge=0) :
		catAge(intialAge)
	{
		cout << "cat cons" << endl;
	}

	cat(cat& t) :
		catAge(t.catAge)
	{
		cout << "cat copy" << endl;
	}

	~cat() { cout << "cat des" << endl; }
private:
	int catAge;

};
class dog
{
public:
	dog(int intialAge) :
		dogAge(intialAge)
	{
		cout << "dog cons" << endl;
	}

	dog(dog& t) :
		dogAge(t.dogAge)
	{
		cout << "dog copy" << endl;
	}

	~dog() {
		cout << "dog des" << endl;
	}
private:
	int dogAge;

};

class zoo {
public:
	zoo(cat a, dog b, int t) :
		zooDog(b), zooAge(t),zooCat(a)//成员初始化顺序与类中定义顺序一致
	{
		cout << "zoo con" << endl;
	}

	zoo(zoo& zoot) :zooCat(zoot.zooCat), zooDog(zoot.zooDog), zooAge(zoot.zooAge)
	{
		cout << "zoo copy" << endl;
	}

	~zoo() { cout << "zoo des" << endl; }
private:
	cat zooCat;
	dog zooDog;
	int zooAge;
};

cat outPut(cat cat1) {
	cout << 1 << endl;
	return cat1;
}

dog outPut(dog dog1) {
	cout << 2 << endl;
	return dog1;
}

int main()
{
	cat cat1(1);
	dog dog1(4);
	cout<<endl;
	zoo zoo1(outPut(cat1), outPut(dog1), 6);
	system("pause");
	return 0;
}

原因分析:

初步猜测
可能是函数调用过程中返回了const的类型导致拷贝构造函数不能接收出现编译报错:
没有匹配的函数。
查阅了两天资料后

精简后的测试代码:

#include <iostream>
using namespace std;
class cat
{
public:
	cat(int intialAge = 0) : catAge(intialAge){
		cout << "cat cons" << endl;
	}

	cat(cat& t) : catAge(t.catAge) {
		cout << "cat copy" << endl;
	}

	~cat() { cout << "cat des" << endl; }

private:
	int catAge;
};
cat outPut(cat cat1) {
	cout << 1 << endl;
	return cat1;
}
int main()
{
	cat cat1(1);
	cout << endl;
	outPut(outPut(cat1));
	system("pause");
	return 0;
}

解决方案:

1、自定义移动构造函数

#include <iostream>
using namespace std;
class cat
{
public:
	cat(int intialAge = 0) : catAge(intialAge){
		cout << "cat cons" << endl;
	}

	cat(cat& t) : catAge(t.catAge) {
		cout << "cat copy" << endl;
	}

	cat(cat&& t) : catAge(t.catAge) {
		cout << "cat copy" << endl;
	}

	~cat() { cout << "cat des" << endl; }

private:
	int catAge;
};
cat outPut(cat cat1) {
	cout << 1 << endl;
	return cat1;
}
int main()
{
	cat cat1(1);
	cout << endl;
	outPut(outPut(cat1));
	system("pause");
	return 0;
}

2、将复制构造函数形参声明为const的引用

#include <iostream>
using namespace std;
class cat
{
public:
	cat(int intialAge = 0) : catAge(intialAge){
		cout << "cat cons" << endl;
	}

	cat(const cat& t) : catAge(t.catAge) {
		cout << "cat copy" << endl;
	}

	~cat() { cout << "cat des" << endl; }

private:
	int catAge;
};
cat outPut(cat cat1) {
	cout << 1 << endl;
	return cat1;
}
int main()
{
	cat cat1(1);
	cout << endl;
	outPut(outPut(cat1));
	system("pause");
	return 0;
}

原因分析:

C++ Primer(5th) 202页 引用返回左值一讲中提到:
函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值,其他返回类型得到右值,可以像使用其他左值那样来使用返回引用的函数的调用,特别是,我们能为返回类型是非常量引用的函数的结果赋值。
暂时还没有弄清楚为什么函数返回是右值,在这里不妨假设这个右值就是const cat类型的;
当复制构造函数形参为cat&,即为左值引用cat类型,故不能将一个右值赋值给左值引用类型,可用如下代码表示该错误。

const cat& cat5(5);
cat& cat1 = cat5;

解决方案一原因分析:

移动构造函数形参为cat&&,是一个右值引用,可以接收返回类型为右值的参数。
即相当于:

const cat cat5(5);
cat&& cat1 = const cat cat5;

解决方案二原因分析:

复制构造函数形参为const cat&,是一个左值常量引用,可以用右值对其初始化。

const cat cat5(5);
const cat& cat1 = const cat cat5;

总结

当调用的函数返回一个非引用类型的对象时,返回值为右值,此时若想直接用该对象拷贝初始化令一个对象,则需要
1.将复制构造函数形参列表定义为常量类型
或者
2.自定义移动构造函数

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值