C++ 为什么我们需要从一种类型显式转换为另一种类型
C++ Why do we need to explicitly cast from one type to another?
我最近在写一些代码,发现自己做了很多c风格的转换,如下所示:
Client* client = (Client*)GetWindowLong(hWnd, GWL_USERDATA);
我心想,为什么我们真的需要做这些?
我可以有点理解为什么在有很多代码的情况下需要这样做,其中编译器可能无法将哪些类型转换为什么类型,例如使用反射时。
但是当从长型转换为两种类型大小相同的指针时,我不明白为什么编译器不允许我们这样做?
当从长型转换为两种类型大小相同的指针时,我不明白为什么编译器不允许我们这样做?
具有讽刺意味的是,这是编译器干预最重要的地方!
在绝大多数情况下,在long
和指针之间进行转换是一个编程错误,即使您的平台允许,您也不想被忽视。
例如,当你写这个
unsigned long *ptr = getLongPtr();
unsigned long val = ptr; // Probably an error
几乎可以肯定的是,您在ptr
前面缺少一个星号:
unsigned long val = *ptr; // This is what it should be
在没有编译器帮助的情况下发现这样的错误是非常困难的,因此编译器希望您告诉它您知道何时进行这样的转换。
此外,在一个平台上很好的东西可能不适用于其他平台。例如,整型类型和指针在 32 位平台上可能具有相同的大小,但在 64 位平台上具有不同的大小。如果要保持任何程度的可移植性,编译器即使在大小相同的 32 位平台上也应警告您转换。编译器警告将帮助您识别错误,并切换到可移植的指针作为整数类型intptr_t
。
这个想法是我们希望编译器告诉我们何时在做一些狡猾和/或可能无意的事情。这样我们就不会偶然这样做。所以编译器会抱怨,除非我们明确告诉编译器这是我们真正想要的。我们通过使用 a 强制转换来做到这一点。
编辑添加:
最好问问为什么允许我们在类型之间进行转换。最初C
是作为强类型语言创建的。虽然它允许在相关对象类型之间(如整数和浮点数之间)进行升级/转换,但它应该防止访问和分配给错误的类型作为语言功能,这是一种安全措施。然而,有时这很有用,因此在语言中放置了强制转换,以允许我们在需要的时候规避类型规则。
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 在运行时检查继承是否只有一种类型和 void*
- 文本冒险游戏 - 如何区分一种项目类型与另一种项目类型以及如何构建项目类/子类
- 当 c++ 需要一种数据类型并获取另一种数据类型时会发生什么?
- 在硬件SIMD矢量指针和相应类型之间进行"interpret_cast"是一种未定义的行为吗
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- void* 数组将元素转换为另一种类型
- 使用字节向量作为其他类型的原始存储是一种好的做法吗
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 将一种类型的比特重新解释为不同类型的比特的技术
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 在枚举类型上使用std::max是不是一种糟糕的做法
- 为什么需要类型名称,即使似乎足以推断名称应该是一种类型?
- 在 c++ 中将一种结构类型分配给另一种类型
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 我怎样才能让编译器推导出一种类型的 nullptr
- 如何测试指针类型是否可以安全地转换为另一种指针类型?
- 有没有一种很好的方法来实现具有默认失败情况的条件类型?
- 一种类型的多个 cv 分解
- 如何将对象定义为一种类型,然后再将其声明为子类型