explicit关键字
explicit关键字
explicit关键字
在理解 explicit 关键字 之前,我们必须要了解构造函数的类型转换作用,以便于我们更好的理解 explicit 关键字 ,如果有不懂构造函数,可以来看看这篇文章:构造函数
点击查看代码
class Date
{
public:
// 构造函数
Date(int year)
:_year(year)
{
}
private:
int _year;
int _month = 3;
int _day = 31;
}
在C++中,仅仅在类的定义内部(即在类的大括号{}内)声明并定义成员函数,并不意味着该函数自动成为内联函数。然而,通常我们倾向于将这样的成员函数视为内联的候选者,因为编译器在处理它们时会有更高的可能性进行内联展开。
要使函数真正成为内联的,你可以在函数声明前使用inline关键字。然而,在类定义内部定义的成员函数,即使没有inline关键字,编译器也可能会选择对其进行内联优化,特别是当函数体很小且频繁被调用时。
点击查看代码
class MyClass {
public:
MyClass(int value) : data(value) {}
// 虽然没有使用inline关键字,但编译器可能会选择内联这个函数
int getValue() {
return data;
}
// 显式地使用inline关键字
inline void setValue(int value) {
data = value;
}
private:
int data;
};
- 对于下面的 d1 很清楚一定是调用了有参构造进行初始化,不过对于 d2 来说,也是一种构造方式
点击查看代码
int main()
{
// d1 和 d2 都会调用构造函数
Date d1(2022);
Date d2 = 2023;
return 0;
}
-
在引用详解,我有提到过【隐式类型转换】这个概念,像下面将一个int类型的数值赋值给到一个double类型的数据,此时就会产生一个隐式类型转换
int i = 1;
double d = i;
-
对于类型转换而言,这里并不是将值直接赋值给到左边的对象,而是在中间呢会产生一个临时变量,例如右边的这个 i 会先去构造一个临时变量,这个临时变量的类型是 [double] 。把它里面的值初始化为 1,然后再通过这个临时对象进行拷贝构造给d,这就是编译器会做的一件事
-
那对于这个 d2 其实也是一样,2023会先去构造一个临时对象,这个临时对象的类型是[Date]把它里面的year初始化为2023,然后再通过这个临时对象进行拷贝构造给到d2,
点击查看代码
//拷贝构造
Date(const Date& d)
:_year(d._year)
,_month(d._month)
,_day(d._day)
{
}
【拷贝构造】也是属于构造函数的一种哦,也是会有初始化列表的
编译器在这里地方做了一个优化,将【构造 + 拷贝构造】优化成了【一个构造】,因为编译器在这里觉得构造再加拷贝构造太费事了,干脆就合二为一了。其实对于这里的优化不同编译器是有区别的,像一下VC++、DevC++可能就不会去优化,越是新的编译器越可能去进行这种优化。
怎么知道中间赋值这一块产生了临时对象呢?如果不清楚编译器的优化机制这一块肯定就会认为这里只有一个构造?
Date& d3 = 2024;
报错