【C++基础知识】初始化列表,单参构造函数的隐式类型转换

初始化列表:

​ 以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个成员变量后面跟一个放在括号中的初始值或表达式。

例如:

class Date
{
    
    
public:
 Date(int year, int month, int day): _year(year), _month(month), _day(day)
 {
    
    }
 
private:
 int _year;
 int _month;
 int _day;
};

1.每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
2.三类成员必须在初始化列表中进行初始化:引用成员变量,const成员变量,没有默认构造函数的自定义成员。
3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

思考下面这段代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;
class A {
    
    
public:
	A(int a):a1(a),a2(a1)
	{
    
    
		cout << a1 << " " << a2 << endl;
	}
private:
	int a2;
	int a1;

};
int main()
{
    
    
	A a(1);
	return 0;
}

输出结果:

在这里插入图片描述

a1=1, a2为随机值。

单参构造函数的隐式类型转换 explicit关键字

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class A {
    
    
public:
	A(int a) :_a(1)
	{
    
    
		cout << "A()" << endl;
	}
private:
	int _a;
};

int main()
{
    
    
	A obj1(1);
	A obj2 = obj1;
	A obj3 = 20;
	return 0;
}

阅读上面这段代码,看第18行,直接用整数20去初始化类A的对象obj3,这是不合逻辑的,但是这段代码在编译器中却是可以正常运行的。这是因为编译器内部进行了优化,在执行该语句时,编译器会先用整数20初始化一个临时的无名对象,然后用该临时对象给obj3进行赋值,这种现象称为单参构造函数的隐式类型转换。(注意:只有单参数的构造函数可以编译通过!!!)

那么如何解决该问题呢?

​ 此处我们引入explicit关键字,在定义构造函数时,在函数名之前加上explicit关键字就可以避免发生这种情况。

猜你喜欢

转载自blog.csdn.net/weixin_43962381/article/details/114373258