概述
explicit只能修饰构造函数,构造函数默认implicit,implicit不是keyword
- implicit构造函数:可用于直接初始化,也可用于复制初始化
- explicit构造函数:可用于直接初始化,不可用于复制初始化
implicit
class CAnimal
{
public:
CAnimal(int group) : mGroup(group)
{
cout << "CAnimal(" << group << ")" << endl;
}
CAnimal(const CAnimal &other) : mGroup(other.mGroup)
{
cout << "CAnimal(const CAnimal &other) " << mGroup << endl;
}
CAnimal& operator=(const CAnimal &other)
{
mGroup = other.mGroup;
cout << "CAnimal operator= " << mGroup << endl;
return *this;
}
private:
int mGroup;
};
void implicit_construct()
{
{
cout << "-----init-----" << endl;
CAnimal animal1(1);
CAnimal animal2 = 2;
CAnimal animal3(animal1);
CAnimal animal4 = animal2;
}
{
cout << "-----assign-----" << endl;
CAnimal animal1(1);
CAnimal animal2(2);
animal2 = animal1;
animal2 = 3;
}
}
output:
-----init-----
CAnimal(1)
CAnimal(2)
CAnimal(const CAnimal &other) 1
CAnimal(const CAnimal &other) 2
-----assign-----
CAnimal(1)
CAnimal(2)
CAnimal operator= 1
CAnimal(3)
CAnimal operator= 3
explicit
class CAnimal
{
public:
explicit CAnimal(int group) : mGroup(group)
{
cout << "CAnimal(" << group << ")" << endl;
}
explicit CAnimal(const CAnimal &other) : mGroup(other.mGroup)
{
cout << "CAnimal(const CAnimal &other) " << mGroup << endl;
}
CAnimal& operator=(const CAnimal &other)
{
mGroup = other.mGroup;
cout << "CAnimal operator= " << mGroup << endl;
return *this;
}
private:
int mGroup;
};
void explicit_construct()
{
{
cout << "-----init-----" << endl;
CAnimal animal1(1);
//CAnimal animal2 = 2;
CAnimal animal3(animal1);
//CAnimal animal4 = animal1;
}
{
cout << "-----assign-----" << endl;
CAnimal animal1(1);
CAnimal animal2(2);
animal2 = animal1;
//animal2 = 3;
}
}
output:
-----init-----
CAnimal(1)
CAnimal(const CAnimal &other) 1
-----assign-----
CAnimal(1)
CAnimal(2)
CAnimal operator= 1
总结
- CAnimal animal = value,复制初始化,如果构造函数CAnimal(value)为implicit,正确初始化,如果为explicit,编译error
- CAnimal &other = value,初始化式期望右值value为CAnimal类型,若value为非CAnimal类型,如果构造函数CAnimal(value)为implicit,生成匿名CAnimal对象,如果为explicit,编译error
- implicit构造函数可用于直接初始化,也可用于复制初始化
- explicit构造函数可用于直接初始化,不可用于复制初始化
- 复制初始化只允许传递1个参数
直接初始化VS复制初始化
非类类型
- 非类类型直接初始化和复制初始化无区别,值复制
类类型
- 直接初始化可使用implicit构造函数,也可使用explicit构造函数
- 复制初始化可使用implicit构造函数,不可使用explicit构造函数
- 复制初始化只允许传递1个参数
class CAnimal
{
public:
CAnimal(int group, int subGroup = 1) : mGroup(group), mSubGroup(subGroup)
{
cout << "CAnimal(" << group << ", " << subGroup << ")" << endl;
}
CAnimal(const CAnimal &other) : mGroup(other.mGroup)
{
cout << "CAnimal(const CAnimal &other) " << mGroup << endl;
}
CAnimal& operator=(const CAnimal &other)
{
mGroup = other.mGroup;
cout << "CAnimal operator= " << mGroup << endl;
return *this;
}
private:
int mGroup;
int mSubGroup;
};
void construct()
{
CAnimal animal1(5);
CAnimal animal2(5, 8);
CAnimal animal3 = 5;
CAnimal animal4 = (5, 8);
}
output:
CAnimal(5, 1)
CAnimal(5, 8)
CAnimal(5, 1)
CAnimal(8, 1)
注:(5, 8)为逗号表达式,值为8,因此CAnimal animal4 = (5, 8)等价于CAnimal animal4 = 8,最终转换为CAnimal animal4(8)