文章插图
作者 | 樱雨楼
责编 | 胡雪蕊
出品 | CSDN(ID:CSDNnews)
1.引言不同的数据在计算机内存中的存储方式不同,导致了“类型”这一抽象概念的出现 。
对于一个变量而言,其必须要回答三个问题:
1. 在哪可以访问到这个变量的起点?
2. 从起点向后需要读取多少内存?
3. 应该如何解析读取到的二进制数据?
上述的三个问题中,问题 1,由内存地址回答,问题 2 和 3,均由类型回答 。
由此可见,类型与内存地址共同构成了一个变量的完整组分 。之所以不能对 void 取值,也是由于无法回答问题 2 和 3 导致 。
进一步的,我们可以得到一条十分重要的结论:对于两个不同类型的变量,由于其对问题 2 和 3 的答案不同,故如果将这样的两个变量直接进行运算,在绝大多数情况下都将无法产生有价值的计算结果 。
故在几乎所有的编程语言中都有一条重要的规定:不同类型的两个变量无法直接进行运算 。
虽然不同类型的两个变量无法进行运算,但显然,我们可将其中的一个变量通过类型转换,转为与另一个变量类型一致,此时就满足“同类型变量才能进行运算”这一规定了 。
同时,由于某些类型转换是“理所应当”的,而另一些不是,故由此又派生出两个概念:隐式类型转换与显式类型转换 。
隐式类型转换指不通过专门的类型转换操作,而是通过其它规定或代码上下文隐式发生的类型转换,而显式类型转换则通过专门的类型转换操作进行转换,显式类型转换具有强制性,其将不受任何类型转换以外的因素影响,故显式类型转换又称为强制类型转换。
在 C++ 中,类型转换是一个非常复杂的话题 。本文将先从隐式类型转换入手,逐步讨论各类 C++ 的类型转换话题 。
2.类型提升与算术类型转换算术类型转换专指 C++ 提供的各种内置算术类型之间的隐式类型转换 。
内置算术类型主要包括以下类型:
1. bool
2. char, signed char, unsigned char
3. short, int, long, long long, unsignedshort, unsigned int, unsigned long, unsigned long long
4. float, double, long double
5. size_t, ptrdiff_t, ptr_t 等其它特殊类型
算术类型转换是一类不完全明确的,且与底层密切相关的隐式类型转换 。
其遵循以下几条主要原则:
1. 对于同类算术类型,如short 与 int,float 与 double,占用较小内存的类型将转换成另一类型 。如 short+ int将被转换为 int + int 。此种类型转换称为类型提升 。
2. 整形将转为浮点型 。如 int+ double 将被转换为 double + double 。
3. 仅当无符号类型占用的内存小于有符号类型时,无符号类型才发生类型提升从而转为有符号类型,否则,有符号类型将转为无符号类型 。这是一个非常需要注意的点 。
参考以下代码:
int main{unsigned short a = 1;unsigned b = 1;cout << (a > -1) << " " << (b > -1) << endl; // 1 0!}上述代码中,-1 作为 int 直接量而存在,由于变量 a 是unsigned short 类型,故其将被转为 int,值仍为 1 。
但由于变量 b 的类型是与 int 同级的 unsigned 类型,故此时 -1 将被转为 unsigned 类型,这明显不是我们需要的结果 。
由此可见,当有符号类型与无符号类型(如 size_t)发生混用时,一定要小心可能会发生的隐式类型转换 。
3.转换构造函数3.1 定义转换构造函数
C++ 中,如果一个构造函数满足以下所有条件,则其成为一个转换构造函数:
1. 至多有一个不含默认值的形参 。这主要包括以下几种情况:
- 构造函数只有一个形参
- 构造函数有不止一个形参,但只有第一形参无默认值
- 构造函数有不止一个形参,但全部形参均有默认值
如果一个类定义了某种转换构造函数,则被定义的类型将可以通过任何类型转换方式转为当前类类型 。这常见于以下几种情况:
1. 赋值时发生的隐式类型转换
2. 实参传递时发生的隐式类型转换
3. 基于 static_cast 的显式类型转换
参考以下代码:
c++struct A { A (int) {} }; // 转换构造函数void test(A) {}int main{A _ = 0; // 赋值时发生的隐式类型转换test(0); // 实参传递时发生的隐式类型转换}上述代码中,我们为类A 定义了从 int 到 A 的转换构造函数 。则此时,我们既可以将一个 int 直接赋值给类型为 A 的变量,也可以直接将一个 int 作为实参传给类型为 A 的形参 。这两种情况发生时,都隐式地通过转换构造函数构造了类 A 的一个实例 。
推荐阅读
- 梦见猴子缠着我甩不掉最后死了 梦见猴子缠着我甩不掉如何甩掉
- 局域网MAC地址认证上网如何实现
- C和C++标准库,这是什么玩意?
- 喝茶前如何洗茶 避免误操作的三大要领
- VLAN工作原理之ACCESS:接收到带VLAN的报文如何处理
- 如何选购与冲泡陈年普洱茶
- 胡萝卜炖排骨汤如何做才好吃?
- 红茶有哪些类别红茶类别如何区分
- 170男生如何穿搭,穿搭显高秘籍都在这里了,快来学习吧
- 阿里巴巴网店怎么开啊流程是怎样 如何阿里巴巴开店步骤