1、如果构造函数只接受一个实参,则他实际上定义了转换为此类类型的隐式转换机制(即implicit),经常见的例子如下:
string s("flag"); //调用string 只有一个实参的构造函数
string s = "falg"; //也可以,此时实际的操作就是:
// string temp("flag"); s = temp;(拷贝)
2、显示声明的构造函数和隐式声明的区别如下:
(1)如下隐式声明的情况
#include <iostream>
using namespace std;
struct student
{
student(string s) : name(s){}
//student(const char* p);
string name;
};
int main() {
student s1("alen");
cout << s1.name << endl; //可以正常打印,const char*类型隐式的转换为了string类型
//student s = "jams"; //编译失败,因为入参是string类型,此处的char* 并不会转换为string类型
string str = "jams"; //所以需要将char* 声明为string
student s2 = str;
cout << s2.name << endl; // 可以正常打印,因为所调用构造函数,只接受一个参数,提供了隐式转换机制
return 0;
}
(2)如果不想让用隐式转换的情况,可以使用explicit关键字。explicit关键字的作用就是防止类构造函数的隐式自动转换.
#include <iostream>
using namespace std;
struct student
{
explicit student(string s) : name(s){}
string name;
};
int main() {
student s1("alen");
cout << s1.name << endl; //可以正常打印,const char*类型隐式的转换为了string类型
string str = "jams"; //所以需要将char* 声明为string
student s2 = str; //编译失败,因为explicit关键字限制了隐式转换。
cout << s2.name << endl;
return 0;
}
(3)explicit关键字只对有一个参数的类构造函数有效, 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的, 所以explicit关键字也就无效了.
(4)但是, 也有一个例外, 就是当除了第一个参数以外的其他参数都有默认值的时候, explicit关键字依然有效, 此时, 当调用构造函数时只传入一个参数, 等效于只有一个参数的类构造函数, 如下:
#include <iostream>
using namespace std;
struct student
{
student(string s,int a = 15) : name(s), age(a){}
string name;
int age;
};
int main() {
student s1("alen");
cout << s1.name << endl; //可以正常打印,const char*类型隐式的转换为了string类型
string str = "jams"; //所以需要将char* 声明为string
student s2 = str; //编译成功,因为除了第一个参数以外都有默认值。
//当调用构造函数时只传入一个参数,等效于只有一个参数的类构造函数
cout << s2.name << endl;
return 0;
}