C++隐式类型转换及explicit关键字讲解

目录

一.类型转换

隐式类型转换

强制类型转换

总结:

二.类对象之间的隐式类型变换

explicit关键字:

        使用explicit关键字情况二: 虽然有多个参数,但是创建对象时后两个参数可以不传递。


一.类型转换

隐式类型转换

        隐式类型转换就是编译器默默地、隐式地、偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生。

#include<iostream>
using namespace std;
int main() {
	int a = 10;
	double c = a;	//自动类型转换
	return 0;
}

        代码解析:double c=a;表示变量a会在内层空间外部创建一个临时的变量,里面存储a的数值,然后临时变量的内容进行自动类型转换再拷贝给变量c,之后临时变量被销毁。变量a的值是不会进行类型转换的,编译器转换的只是临时变量。

强制类型转换

        隐式类型转换是编译器根据代码的上下文环境自行判断的结果,有时候并不是那么“智能”,不能满足所有的需求。如果需要,程序员也可以自己在代码中明确地提出要进行类型转换,这称为强制类型转换。

int main() {
	//强制类型转换
	cout << (float)a << endl;
	return 0;

总结:

        强制类型转换是程序员明确提出的、需要通过特定格式的代码来指明的一种类型转换;,隐式类型转换是编译器默默地、隐藏地进行的一种类型转换,不需要在代码中体现出来。换句话说,隐式类型转换不需要程序员干预,强制类型转换必须有程序员干预。

二.类对象之间的隐式类型变换

class Date{
public:
Date(int year)
	:_year(year)
{
	cout << "Date类的构造函数" << endl;
}

Date(const Date& d) {
	_year = d._year;
	_month = d._month;
	_day = d._day;
	cout << "Date类的拷贝构造函数" << endl;
}

~Date() {
	_year = 0;
	_month = 0;
	_day = 0;
	cout << "析构函数调用" << endl;
}

private:
	int _year;
	int _month;
	int _day;
};

int main(){
	Date d1(2022);	//创建对象d1,调用构造函数
	Date d2(d1);	//创建对象d2,调用拷贝构造
	Date d3 = d1;	//也是调用拷贝构造,与语句二等价

	Date d4 = 2022;	
	Date& d5 = 2022;	
}						

        代码解析:Date d4=2022;这条语句编译器采用了隐式类型转换,不仅调用了构造函数还调用了拷贝构造函数,原理就是:2022为int型常量,用int去构造一个Date类的临时对象,这就要用到构造函数了,之后,这个临时对象再调用拷贝构造给d4,所以d4._year=2022。

        但是编译器采用了隐式类型转换(优化),构造+拷贝构造== > 直接构造。所以d4语句的执行只调用了构造函数!

        而Date& d5=2022;也是2022调用构造创建一个临时对象,而d5拷贝构造临时对象,是临时对象的别名。但该句会出现编译错误,因为临时对象具有常性(仅可读),Date&是可读可写,左右权限不等,所以报错。左值应该加const才行。

explicit关键字:

        情况一:对于单参构造函数,没有使用explicit修饰,具有类型转换作用。 

        explicit修饰构造函数,限制了编译器无法使用隐式类型转换--explicit去掉之后,代码可以通过编译。

explicit Date(int year)
		:_year(year)
	{
		cout << "Date类的构造函数" << endl;
	}

        使用explicit关键字情况二: 虽然有多个参数,但是创建对象时后两个参数可以不传递。

class Date
{
public:

	// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具
	//有类型转换作用
		// explicit修饰构造函数,禁止类型转换
		 Date(int year, int month = 1, int day = 1)	//部分缺省
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main() {
	Date d1 = 2030;
	//这个也具有隐式类型转换,自动转换为Date d1(2030);
	return 0;
}

         C++11版本后:即使构造函数中没有缺省值,对象也可以传所有参数进行隐式类型转换。但需要用一对花括号包含实参。

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

int main() {
	//Date d1 = 2022, 10, 12;		//报错
	//Date d2 = (2022, 10, 12);	//报错
	Date d3 = { 2022,10,12 };
	//d3具有隐式类型转换,d3这条语句等价于 Date d3(2022,10,12);
	const Date& d4 = { 2022,10,12 };	//也涉及隐式类型转换,临时对象具有常性,需要const

	//注:以上之所以能进行隐式类型转换,是因为构造函数处没有explicit关键字,
	return 0;

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙予清的zzz~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值