拷贝构造函数
一个构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值。(参数可以是 const 引用,也可以是非 const 引用。 一般使用前者)
拷贝构造函数在几种情况下都会被隐式地使用。因此,拷贝构造函数通常不应该是explicit的
拷贝构造函数调用的情况
- 一个对象作为函数参数,以值传递的方式传入函数体
- 一个对象作为函数返回值,以值传递的方式从函数返回
- 一个对象用于给另外一个对象进行初始化(常称为赋值初始化)等号右侧对象拷贝到正在创建的对象中,如果需要还需进行类型转换(拷贝初始化没有=号的情况)
- 使用{}列表初始化一个数组中的元素或聚合类中的成员。
class Sales_data
{
public:
Sales_data(const Sales_data&);
Sales_data();
std::string bookNo;
int units_sold = 0;
double revenue = 0.0;
};
Sales_data::Sales_data(const Sales_data& orgig):bookNo(orgig.bookNo),units_sold(orgig.units_sold),revenue(orgig.revenue)
{
using namespace std;
cout << " copy Sales_data" << endl;
}
Sales_data::Sales_data()
{
using namespace std;
cout << " init Sales_data" << endl;
}
class Person
{
public:
std::string name;
int height;
};
Sales_data returnNoConst()
{
Sales_data sales_data;
sales_data.bookNo = "123";
sales_data.revenue = 1.1;
sales_data.units_sold = 2;
return sales_data;
}
int main()
{
Sales_data sales_data; // 默认构造函数
sales_data.bookNo = "123";
sales_data.revenue = 1.1;
sales_data.units_sold = 2;
returnNoConst(); // 拷贝构造函数
Sales_data sales_datas[3] = { sales_data ,sales_data ,sales_data }; // 拷贝构造函数
Sales_data sales_data1 = sales_data; // 拷贝构造函数
Sales_data sales_data2( sales_data);// 拷贝构造函数
Person person = { "xiaohong",10 };// 拷贝构造函数
//Sales_data sales_data2 = sales_data;
//Sales_data sales_data3(sales_data2);
}
输出结果
为什么拷贝构造函数的参数必须是引用类型?
如果一个函数是通过值传递而不是引用传递的话,那么它真正传递的其实是实参的副本,该副本产生必定会调用拷贝构造函数。
那么,试想一下,,如果我们的拷贝构造函数是通过值传递的话,它就会调用它本身来产生一个副本,就这样会无限递归下去,而如果传递引用,就不会产生副本,也不会调用拷贝构造函数,问题得以解决。
delete来指定不生成拷贝构造函数(对象就不能通过值传递)
#pragma once
#include <string>
class Sales_data
{
public:
Sales_data(const Sales_data&) = delete;
Sales_data();
std::string bookNo;
int units_sold = 0;
double revenue = 0.0;
};