静态强制转换允许转换对象指针,但不允许转换整数

Static cast allows conversion of object pointers but not integers

本文关键字:转换 指针 对象 不允许 整数 许转换 静态      更新时间:2023-10-16

为什么静态强制转换允许在指向派生或基的指针之间进行向上转换或向下转换,如下所示,但是在 char* 和 int* 之间进行转换的情况下,反之亦然 int* 到 char*,则会出现编译错误?

我相信,在不同的对象指针之间进行转换同样糟糕。

// compiles fine
class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * bc = static_cast<Derived*>(a);
// Gives an invalid static cast error during compilation
char charVar = 8;
char* charPtr = &charVar;
int* intPtr = static_cast<int*>(charPtr);

C++强烈地以性能为导向。因此,只要有一些用例可以获得性能,C++就会允许您这样做。考虑std::vector:当然,可以通过功能at进行安全元素访问,它会为您进行范围检查。但是,如果您知道您的索引范围内(例如在 for 循环中(,这些范围检查只是自重。因此,您还会得到(不太安全的(operator[],它只是省略了这些检查。

同样,如果你有一个类型的指针Base,它实际上可以指向Derived类型的对象。如有疑问,您将从Base*dynamic_castDerived*.但这会带来一些开销。但是,如果您 100% 确定(通过任何方式......(子类实际上是什么,您是否需要此开销?由于从Derived*Base*有一种自然的(甚至是隐含的!(方式,我们希望有一些低成本的回归方式。

另一方面,在完全不相关的类型(例如charint或两个不相关的类(的指针之间没有这种自然转换,因此没有这种低成本的返回方式(与dynamic_cast相比,当然,这也不可用(。在两者之间转换的唯一方法是reinterpret_cast

实际上,reinterpret_cast也不收取任何费用,它只是将指针解释为不同的类型 - 具有所有风险!如果需要static_castreinterpret_cast甚至可能会失败(防止"为什么不总是使用......"的问题的权利(:

class A { int a; };
class B { };
class C : public A, public B { };
B* b = new C();
C* c = reinterpret_cast<C*>(b); // FAILING!!!

从内存布局的角度来看,C看起来像这样(即使隐藏在你之外(:

class C
{
A baseA;
B baseB; // this is what pointer b will point to!
};

显然,在C*B*(任一方向(之间进行铸造时,我们会得到偏移量,static_castdynamic_cast都认为这一点,但reinterpret_cast不会......

为什么静态投射允许上播...

没有理由防止上流。事实上,派生指针甚至可以隐式转换为基指针 - 不需要强制转换(除非在有多个相同类型的基的复杂情况下(。派生类对象始终包含基类子对象。

向上转换特别有用,因为它允许通过使用虚函数进行运行时多态性。

或在指向派生或基数对象的指针之间向下转换,如下所示

基指针可能指向派生对象的基子对象,这是向上转换的结果。比如这里:

Derived d;
Base *b = &d;

在某些情况下,您可能希望访问已知正在指向的派生对象的成员。静态强制转换使这成为可能,而无需花费运行时类型信息。

编译器通常不可能(在编译时(找出指向对象的具体类型(即指针是否指向子对象,如果是,则容器对象的类型是什么(。程序员有责任确保满足演员的要求。如果程序员不能证明正确性,那么编写静态强制转换就是一个错误。

这是因为您要做的是重新解释 - 对此有一个reinterpret_cast<>运算符。 指针的static_cast<>仅用于向下投射:

    如果new_type是指向某个类 D 的指针或引用,
  1. 并且表达式类型是指向其非虚拟基 B 的指针或引用,则static_cast执行向下转换。如果 B 是 D 的不明确、不可访问或虚拟基(或虚拟基的基(的,则此向下转换格式不正确。此类static_cast不进行运行时检查以确保对象的运行时类型实际上是 D,并且只有在通过其他方式(例如在实现静态多态性时(保证此前提条件时才能安全使用。安全的下落可以通过dynamic_cast来完成。

看:

何时应使用static_cast、dynamic_cast、const_cast和reinterpret_cast?

详细讨论何时使用每个铸造操作员。