C++ 对于类型的要求极为严格,猜想下面的代码能否通过编译?
1 | array<int, 6> a1; |
我们可能需要在我们的代码中执行类型转换操作,例如把 int 类型的变量转变为 double 类型的变量,将派生类转变为父类…..
C++ 一共提供以下的各种类型的类型转换方式
1 | // 旧式的类型转换 |
使用类型转换时的注意事项
尽可能的避免类型转换
正如文章开头提到的一样,C++对于类型有着严格的规定,我们不可能想其他语言一样,用“等于”符号就能解决问题。当我们在代码中进行类型的转换时,我们通常需要按照C++规定的形式(上面给出的6种形式),才能完成类型的转换任务。
我们除了要按照C++的规定严格的执行之外,我们还需要注意 “另一些的规则”。
- 尽可能的应用新式的类型转换
虽然旧式类型转换和新式的类型转换能够做的事情一样,但是很明显新式的类型转换更容易被辨认出来,编译器也更容易帮助我们进行检查。1
2
3
4
5
6
7
8
9//唯一推荐使用旧式类型转换的场景
调用一个 explicit 构造函数将一个对象传递给另一个对象
class Widget{
public:
explicit Widget(int size){
//...
}
}
Widget w(Wiget(1024)); - 有些版本的 dynamic_cast 转换可能实现的很慢
- 有些版本的 reinterpret_cast 不具有可移植性
尽可能的避免使用类型转换
首先,我们需要知道的一点是: 类型转换并不是简单的告诉编译器哪里需要执行类型转换,编译器需要做的事情实际上也发生了明显的变化。
1 | //编译器对于 double 和 x 的处理,并不相同 |
编译器需要为类型转换付出行动,类型转换是需要付出代价的
而在 《effective STL》一书中,作者更是对于随意的使用类型转换嗤之以鼻。当我们需要将标准容器(standard container)中的 const_iterator 转变成 iterator 时(从 const_iterator 到 iterator 没有显式转换),下面的代码并不能完成任务:
1 | deque<int>::const_iterator ci; |
因为 iterator 和 const_iterator 是两个不一样的类。字面上的 const 并不能说明两者的类型并不相同。
1 | typedef __deque_iterator<T, T&, T*> iterator; |
作者给出的解决方案很简单,利用 distance 和 advance 来实现容器的 将 const_iterator 转换成 (non-const) iterator。
1 | deque<int> d; |