为什么静态强制转换允许在指向派生对象或基的指针之间进行向上转换或向下转换,但如果是在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);发布于 2018-06-04 17:12:25
C++是面向性能的。因此,只要有一些用例,您就可以获得性能,C++将允许您这样做。考虑std::vector:当然,可以通过函数at进行安全的元素访问,它为您进行范围检查。但是,如果您知道您的索引在范围内(例如,在一个for循环中),这些范围检查只是自重。因此,您还可以得到(不太安全的) operator[],它只是省略了这些检查。
类似地,如果您有一个Base类型的指针,它实际上可以指向Derived类型的对象。如果有疑问,您可以从dynamic_cast Base*到Derived*。但这也带来了一些开销。但如果你能百分百肯定的话.子类实际上是什么,您想要这个开销吗?因为有一种自然的(甚至隐含的!)从Derived*到Base*,我们想要一些低成本的回头路。
另一方面,完全不相关类型的指针(例如char和int或两个无关的类)之间没有这样的自然转换,因此没有这样低成本的返回方式(与dynamic_cast相比,dynamic_cast当然也是不可用的)。在两者之间进行转换的唯一方法是reinterpret_cast。
实际上,reinterpret_cast也是免费的,它只是将指针解释为一种不同的类型--所有的风险!如果需要的话,reinterpret_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_cast和dynamic_cast都考虑的,但reinterpret_cast没有考虑到。
发布于 2018-06-04 16:50:52
为什么静态演员允许一个上向演员..。
没有理由阻止上流社会。实际上,派生指针甚至可以隐式转换为基本指针--不需要强制转换(除非在有多个相同类型的基的复杂情况下除外)。派生类对象始终包含基类子对象。
Upcasting特别有用,因为它允许通过使用虚拟函数来实现运行时多态性。
或在指向派生对象或基对象的指针之间向下转换,如下所示
基指针可以指向派生对象的基子对象,这是向上转换的结果。比如这里:
Derived d;
Base *b = &d;在某些情况下,您可能希望访问指定指向的派生对象的成员。静态强制转换可以在不需要运行时类型信息的情况下实现这一点。
一般来说,编译器不可能(在编译时)找出指定对象的具体类型(即指针是否指向子对象,如果指针指向子对象,容器对象的类型是什么)。程序员有责任确保转换的要求得到满足。如果程序员无法证明其正确性,则编写静态强制转换是一个错误。
发布于 2018-06-04 16:51:09
这是因为你要做的是重新解释--其中有一个reinterpret_cast<>操作符。指针的static_cast<>是只用于下浇铸
请参见:
有关何时使用每个铸造操作符的详细讨论。
https://stackoverflow.com/questions/50684795
复制相似问题