C++ explicit 关键字

一、explicit 的意义


先说作用

主要是为了防止发生隐式转换

那么,什么叫隐式转换呢

看下列代码

int main(int argc, char* argv[])
{
	int a = 3;    // int 类型
	double b = a; // a 被隐式转换成 double 在赋值给 b

	return 0;
}

隐式转换总是编译器自动完成的,从小字节自动隐式转换成大字节

但反过来的话,友好的编译器会给我们发出警告,例如以下

int main(int argc, char* argv[])
{
	double a = 3;    
	int b = a; 

	return 0;
}

给出警告

 warning C4244: “初始化”: 从“double”转换到“int”,可能丢失数据

这样的方式极大的方便了我们

在方便的同时也有着容易犯错的地方

看下列代码

int main(int argc, char* argv[])
{
	double a = 5 / 2;
	std::cout << a << std::endl;
	return 0;
}

从数学的角度来看,我们所想的,a 应该是 2.5

但从运行结果来说,它不是 2.5

因为隐式,所以看不见

看不见的时候,就会有一些意想不到的东西

当复杂的环境的时候,往往意想不到的都是灾难级别的存在

 那么如何避免

那就是强调显示出来

明确执行

int main(int argc, char* argv[])
{
	double a = (double)5 / (double)2;
	std::cout << a << std::endl;
	return 0;
}

 这就是我们想要的结果

而今天讨论的 explicit 就是这样的作用:显示,强调

二、explicit 的用途


考虑以下代码

#include <iostream>

class A {
public:
	 A(int a):_value(a){}
	 int value() { return _value; }

private:
	int _value;
};

int main(int argc, char* argv[])
{
	A a = 3;
	std::cout << a.value() << std::endl;
	return 0;
}

编译是没有问题的,也可以运行,达到我们预期的目的

 A a = 3; // 存在隐式转换

也没有说这样的不好,至于风险的上边已经分析过

想要强调用户使用时必须要显式调用 

这时,就可以用 explicit 去修饰一下了

修改代码

 编译器不能隐式转换了

那怎么使用呢,以下两种方式都可以

#include <iostream>

class A {
public:
	 explicit A(int a):_value(a){}
	 int value() { return _value; }

private:
	int _value;
};

int main(int argc, char* argv[])
{
	A a = A(3);
	A b(4);
	std::cout << a.value() << std::endl;
	std::cout << b.value() << std::endl;
	return 0;
}

 当有构造函数有多个参数时,比如

class A {
public:
	 A(int a, int b):_value1(a), _value2(b){}
	 int value1() { return _value1; }
	 int value2() { return _value2; }

private:
	int _value1;
	int _value2;
};

你不能多个赋值,比如这样

int main(int argc, char* argv[])
{
    A a = 3,4
    return 0;
}

但 C++11 你可以这样赋值赋值,也是发生隐式转换

int main(int argc, char* argv[])
{
    A a = { 3 , 4};
    return 0;
}

#include <iostream>

class A {
public:
	 A(int a, int b ):_value1(a), _value2(b){}
	 int value1() { return _value1; }
	 int value2() { return _value2; }

private:
	int _value1;
	int _value2;
};

int main(int argc, char* argv[])
{
	A a = { 3 , 4};
	std::cout << a.value1() << std::endl;
	std::cout << a.value2() << std::endl;
	return 0;
}

 

 加上  explicit

 

 

存在默认参数且只有一个参数默认值的情况

当然这也是跟一个参数一样意思了

#include <iostream>

class A {
public:
	 A(int a, int b = 0):_value1(a), _value2(b){}
	 int value1() { return _value1; }
	 int value2() { return _value2; }

private:
	int _value1;
	int _value2;
};

int main(int argc, char* argv[])
{
	A a = 3;
	return 0;
}

加上  explicit

 

三、_End


既然编译器能自动发生隐式转换,这么好用方便,为何还要 explicit

存在即合理

存在即合理

存在即合理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值