直接初始化和拷贝初始化

定义:

  • 如果使用等号(=)初始化一个变量,实际上执行的是“拷贝初始化”,编译器把等号右侧的初始值拷贝到新创建的对象中去。
  • 与之相反,如果不使用等号,则执行的是“直接初始化

示例:

string dots(10,'.');                //直接初始化
string s(dots);                     //直接初始化
string s2 = dots;                   //拷贝初始化
string null_book = "9-999-99999-9"; //拷贝初始化
string nines = string(100,'9');     //拷贝初始化

注:

  1. 直接初始化实际上是要求编译器使用普通的函数匹配来选择与我们提供的参数最匹配的构造函数

  2. 拷贝初始化实际上是要求编译器将右侧运算对象拷贝到正在创建的对象中,通常用拷贝构造函数来完成

拷贝初始化发生的其他情况:

拷贝初始化不仅在用=定义变量时发生,下列情况也发生

  • 将一个对象作为实参传递给非引用类型的形参时
  • 从一个返回类型为非引用类型的函数返回一个对象
  • 当初始化标准库容器或是调用其insert或push成员时(与之相对,用emplace成员创建的元素都进行直接初始化)

拷贝构造函数的形参必须是引用类型的原因:

  如果不是引用类型,为了调用拷贝构造函数,我们必须拷贝它的实参,但为了拷贝实参,我们又需要调用拷贝构造函数,如此无限循环,造成错误。

拷贝初始化的限制:

  当拷贝构造函数前面加了一个explicit关键字时,调用拷贝构造函数不能进行隐式类型转换,但可以进行显示类型转换,如:

vector<int> v1(10); //正确:直接初始化
vector<int> v2 = 10;//错误:接受大小参数的构造函数是explicit的
void f(vector<int>);//f的参数进行拷贝初始化
f(10);//错误:不能用一个explicit的构造函数拷贝一个实参
f(vector<int>(10));//正确:可以进行显示类型转换(f的参数必须接收一个对象)

参考:《C++ Primer》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值