C++ reinterpret_cast 总是 return 结果吗?
C++ does reinterpret_cast always return the result?
我有两个 class,A 和 B。A 是 B 的父 class,我有一个函数接收指向 class 的指针类型 A,检查它是否也是类型 B,如果是,将调用另一个函数,该函数接收指向类型 B 的 class 的指针。
当函数调用另一个函数时,我提供 reinterpret_cast(a) 作为参数。如果这看起来模棱两可,这里有一个代码示例:
void abc(A * a) {
if (a->IsA("B")) { //please dont worry much about this line,
//my real concern is the reinterpret_cast
def(reinterpret_cast<B *>(a));
};
};
所以现在您知道我是如何调用 "def" 的,我想知道 reinterpret_cast 是否实际上 returns 类型 B 的指针作为参数发送给 def。
我将不胜感激任何帮助。
谢谢
您将有一个 B*
类型的指针,但 reinterpret_cast
并不是很好。
如果您确定类型是 B
,请使用 static_cast
,如果不是,请使用 dynamic_cast
并测试指针(如果 dynamic_cast
失败,它returns nullptr
)
见
reinterpret_cast 总是会按照你说的去做 - 这是一把大锤。你可以做到
def(reinterpret_cast<B *>(42));
或
std::string hw = "hello";
def(reinterpret_cast<B *>(hw));
它总是 return 一个可能指向正确类型的指针。它假定您知道自己在做什么
重新解释转换总是return一个指针。它可能只是不是一个有效的指针,因为它实际上指向 B 类型的对象。
如果B有多个基数class,而A不是第一个基数class,reinterpret cast会做错事,无法对指针进行必要的调整。
对于您的用例,您应该使用静态转换,其优点是编译器将检查 B 是否实际上是从 A 派生的,并执行任何需要的调整。额外的检查不会产生运行时开销,但是如果对象实际上不是 B 类型并且程序将任意失败,则不会有警告。
正如其他人所说,reinterpret_cast
是错误的解决方案,请改用 dynamic_cast
:
void abc(A * a) {
B *b = dynamic_cast<B*>(a);
if (b) {
def(b);
}
}
reinterpret_cast
是类型系统损坏的结果。它的行为假定存在一个联合,例如
union {
TypeA anA;
TypeB aB;
} a;
所以
reinterpret_cast< B* >( a );
假设 a 是指向成员 anA 的指针,然后可以传递 aB 地址。
如果该类型是同一 class 层次结构的一部分,那么 static_cast<> 将允许您在编译时找出是否有足够的信息来执行转换。这通常是在 B
是 A
的基数 class 时(单个或多个)。
如果没有足够的信息让 static_cast 工作,那么有可能让 dynamic_cast<> 工作。这是 B
类型以某种方式从 A
.
派生的情况
请务必注意,dynamic_cast<B*>( a )
或 static_cast< B*>( a )
在成功时可能不会产生相同的地址。
那是因为多重继承时,二次继承会在对象中创建多个classes和vtable。发生这种情况时,static_cast、dynamic_cast 调整对象的基地址以找到正确的嵌入 class 基地址。
dynamic_cast 和 static_cast 可能会更改地址,这就是不鼓励 reinterpret_cast 的原因。它可能会产生一个不符合您要求的值。
我有两个 class,A 和 B。A 是 B 的父 class,我有一个函数接收指向 class 的指针类型 A,检查它是否也是类型 B,如果是,将调用另一个函数,该函数接收指向类型 B 的 class 的指针。 当函数调用另一个函数时,我提供 reinterpret_cast(a) 作为参数。如果这看起来模棱两可,这里有一个代码示例:
void abc(A * a) {
if (a->IsA("B")) { //please dont worry much about this line,
//my real concern is the reinterpret_cast
def(reinterpret_cast<B *>(a));
};
};
所以现在您知道我是如何调用 "def" 的,我想知道 reinterpret_cast 是否实际上 returns 类型 B 的指针作为参数发送给 def。 我将不胜感激任何帮助。 谢谢
您将有一个 B*
类型的指针,但 reinterpret_cast
并不是很好。
如果您确定类型是 B
,请使用 static_cast
,如果不是,请使用 dynamic_cast
并测试指针(如果 dynamic_cast
失败,它returns nullptr
)
见
reinterpret_cast 总是会按照你说的去做 - 这是一把大锤。你可以做到
def(reinterpret_cast<B *>(42));
或
std::string hw = "hello";
def(reinterpret_cast<B *>(hw));
它总是 return 一个可能指向正确类型的指针。它假定您知道自己在做什么
重新解释转换总是return一个指针。它可能只是不是一个有效的指针,因为它实际上指向 B 类型的对象。
如果B有多个基数class,而A不是第一个基数class,reinterpret cast会做错事,无法对指针进行必要的调整。
对于您的用例,您应该使用静态转换,其优点是编译器将检查 B 是否实际上是从 A 派生的,并执行任何需要的调整。额外的检查不会产生运行时开销,但是如果对象实际上不是 B 类型并且程序将任意失败,则不会有警告。
正如其他人所说,reinterpret_cast
是错误的解决方案,请改用 dynamic_cast
:
void abc(A * a) {
B *b = dynamic_cast<B*>(a);
if (b) {
def(b);
}
}
reinterpret_cast
是类型系统损坏的结果。它的行为假定存在一个联合,例如
union {
TypeA anA;
TypeB aB;
} a;
所以
reinterpret_cast< B* >( a );
假设 a 是指向成员 anA 的指针,然后可以传递 aB 地址。
如果该类型是同一 class 层次结构的一部分,那么 static_cast<> 将允许您在编译时找出是否有足够的信息来执行转换。这通常是在 B
是 A
的基数 class 时(单个或多个)。
如果没有足够的信息让 static_cast 工作,那么有可能让 dynamic_cast<> 工作。这是 B
类型以某种方式从 A
.
请务必注意,dynamic_cast<B*>( a )
或 static_cast< B*>( a )
在成功时可能不会产生相同的地址。
那是因为多重继承时,二次继承会在对象中创建多个classes和vtable。发生这种情况时,static_cast、dynamic_cast 调整对象的基地址以找到正确的嵌入 class 基地址。
dynamic_cast 和 static_cast 可能会更改地址,这就是不鼓励 reinterpret_cast 的原因。它可能会产生一个不符合您要求的值。