隐式类型转换

在类型较为相近的两个变量中,可以发生隐式类型转换,比如在int和double之间的比较或赋值就能看到有隐式类型转换发生,来看这一段代码:

void Test1()
{
	int a = 1;
	double d = 2.1;
	int res=a > d;
	int c = d;
}

不难看出,由于类型不同,a,d在进行比较的时候,必定产生了隐式类型转换,当类型一致时,方可完成比较。

可是,a和d在比较时发生的隐式类型转换,会不会影响a,d本身?

并不会。a和d在进行隐式类型转换时比较,拿的是中间临时变量来比较。

同样,d赋值给c就会先生成一个int类型的临时变量,然后赋值给c。

如果我想通过这个c来看看这个临时变量的属性,即将c变为&,还能不能进行赋值

void Test2()
{
	int a = 1;
	double d = 2.1;
    int res=a > d;
	int &c = d;
}

编译报错了。这又为什么,为什么提示说int&类型非常量限定,难道把c变量变成常量属性,即在前面用const修饰,就能编译通过吗

void Test2()
{
	int a = 1;
	double d = 2.1;
    int res=a > d;
	const int &c = d;
}

果然,这时候编译器的确没再报错。为什么加上const就能编译通过了?

其实归根结底就是因为临时变量具有常属性 d发生隐式类型转换后中间产生了一个临时变量,这个变量具有常属性,而这个常属性的变量试图赋给一个随时想改变的变量,那不就很扯淡了。再者,根据权限的角度也能说明这个问题,权限不能放大,很明显,这里就是一个权限放大。

以上说的都是内置类型,那自定义类型呢,也会不会有隐式类型转换

在这之前先得创建一个类

class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};
void Test3()
{
	A a1 = 1;
	A a2 = 1.1;
}

编译通过了,并且经过调试可以看到a1确实是变成了1,所以自定义类型也是存在隐式类型转换的

但也并非任何自定义类型都可以进行隐式类型转换,这里只给了一个参数,那如果是多参数呢

class B
{
public:
	B(int b1,int b2)
		:_b1(b1)
		, _b2(b2)
	{}
private:
	int _b1;
	int _b2;
};
void Test4()
{
	B b1(1);
	B b2 = 1;
}

显然,这种写法是错误的,参数数量都对不上怎么可能会是正确的代码。但如果b2这样赋值却是可以的:

B b2 = { 1, 2 };

这是C++在这里的规定,不做过多解释。

内置类型对象 隐式转换成自定义类型对象时一定要注意,能支持这个转换,是有A的int单参数构造函数(支持传一个参数多参数带缺省也可以)支持。

有时候我们可能并不希望隐式类型能够随意转换,由此C++引入了一个关键字:exiplicit

explicit关键字 构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值 的构造函数,还具有类型转换的作用。

class A
{
public:
	explicit A(int a)
		:_a(a)
	{}
private:
	int _a;
};
void Test5()
{
	A a1 = 1.1;
	A a2 = 1;

}

加上explicit关键字后,就限制了隐式类型转换,但也只是限制隐式类型转换。

所以这里想说的是,explicit仍然无法强制类型转换  

另外补充一点,用explicit修饰构造函数,将会禁止构造函数的隐式转换。 

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
隐式类型转换,也称为自动类型转换,是在 C++ 编程中的一种自动转换机制,它发生在当一种类型的值被赋给另一种类型的变量时,或者是作为函数参数传递时,目标类型能够自动推导出源类型的情况。这种转换通常是编译器进行的优化处理,旨在简化代码编写,并尽量减少显式转换的需要。隐式转换遵循一些特定的规则和优先顺序,以保证程序的正确性和一致性。 ### 隐式类型转换的主要特点包括: 1. **大小一致的转换**:如果目标类型比原始类型大,则会从较小类型自动转换到较大类型。例如,从 `char` 到 `int` 的转换就是隐式的。 2. **窄化(截断)**:从较大的类型转换到较小的类型时,可能发生信息丢失的情况,此时被称为“窄化”。例如,从 `long long` 转换为 `short` 将丢失精度。 3. **强制类型转换**:有时候虽然隐式转换是合法的,但为了保持代码的明确性和可读性,程序员可以选择使用 `(类型)表达式` 来进行显式转换。 ### 常见的例子: - **整数间的隐式转换**: ```cpp char ch = 'A'; // 字符常量 int i = ch; // 自动转换为整数 ``` - **浮点数和整数之间的转换**: ```cpp float f = 5.6f; // 浮点数 int i = (int)f; // 显式转换为整数,保留小数部分的信息 ``` - **自动数组初始化**: ```cpp int a = {1}; // 初始化为{1, 0, 0} ``` 在此例中,最后一个元素默认填充零,这是一种隐式行为。 ### 注意事项: - **窄化损失**:在进行窄化转换时,一定要注意是否有信息丢失的风险,特别是涉及数学运算时(比如浮点数转整数)。 - **性能考虑**:过多的隐式转换可能导致编译器生成更复杂的机器码,进而影响程序性能。 - **代码可读性**:尽管隐式转换可以提高代码的简洁度,但过度依赖隐式转换也可能降低代码的可读性和可维护性,尤其是在大型项目中。 理解隐式类型转换有助于编写更高效、更容易维护的 C++ 程序。掌握其工作原理及潜在风险对于成为一个熟练的 C++ 开发人员至关重要。如果你对其他方面感兴趣,欢迎提问!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值