今天我们来谈谈C++中的explicit关键字,可以先看看C++构造函数之初始化列表
构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用
class Date
{
public:
Date(int year)
:_year(year)
{}
private:
int _year;
int _month = 3;
int _day = 31;
};
int main()
{
Date d1(2022);
Date d2 = 2023;
return 0;
}
依旧通过调试来看就会非常清晰,这种写法也会去调用构造函数
int i = 1;
double d = i;
i
会先去构造一个临时变量,这个临时变量的类型是[double]
。把它里面的值初始化为1,然后再通过这个临时对象进行拷贝构造给d
,这就是编译器会做的一件事[Date]
把它里面的year初始化为2023,然后再通过这个临时对象进行拷贝构造给到d2
,小陈:不是说构造函数有初始化列表吗?拷贝构造怎么去初始化呢?
//拷贝构造
Date(const Date& d)
:_year(d._year)
,_month(d._month)
,_day(d._day)
{}
刚才说到了中间会产生一个临时对象,而且会调用构造 + 拷贝构造,那此时我们在Date类中写一个拷贝构造函数,调试再去看看会不会去进行调用
小叶:但您是怎么知道中间赋值这一块产生了临时对象呢?如果不清楚编译器的优化机制这一块肯定就会认为这里只有一个构造
Date& d3 = 2024;
const
做修饰后,就不会出现问题了,这是为什么呢?const
类型修饰对象不会有问题但若是你不想让这种隐式类型转换发生怎么办呢?此时就可以使用到C++中的一个关键字叫做
explicit
explicit Date(int year)
:_year(year)
{}
对于上面所讲的都是基于单参的构造函数,接下去我们来瞧瞧多参的构造函数
//多参构造函数
Date(int year, int month ,int day = 31)
:_year(year)
,_month(month)
,_day(day)
{}
d1
没有问题传入了两个参数,但是若是像上面那样沿袭单参构造函数这么去初始化还行得通吗?很明显不行,编译器报出了错误{}
就可以了,可能你觉得这种写法像是C语言里面结构体的初始化,但实际不是,而是在调用多参构造函数Date d2 = { 2023, 3 };
const Date& d3 = { 2024, 4 };
那要如何去防止这样的隐式类型转换发生呢,还是可以使用到
explicit
关键字吗?
//多参构造函数
explicit Date(int year, int month ,int day = 31)
:_year(year)
,_month(month)
,_day(day)
{}
explicit
关键字做修饰,同样可以起到【禁止类型转换】的作用explicit
关键字依旧可以起到作用·explicit Date(int year, int month = 3,int day = 31)
:_year(year)
,_month(month)
,_day(day)
{}
explicit
修饰构造函数,将会禁止构造函数的隐式转换以上就是本文要介绍的所有内容,感谢您的阅读