在 typeid 检查后使用 reinterpret_cast 有效吗?
Is using reinterpret_cast after typeid check valid?
如果我首先验证指向基 class 的指针属于某种类型(使用 typeid
),是否可以对其执行 reinterpret_cast
以节省一些性能?
class Base {
virtual ~Base() {}
};
class A : Base {};
class B : Base {};
...
class Z : Base {};
之后在某个地方:
void fn(Base & msg) {
const auto & tid = typeid(msg);
if (tid == typeid(A)) {
A * ptr = reinterpret_cast<A*>(&msg);
} else if (tid == typeid(B)) {
B * ptr = reinterpret_cast<B*>(&msg);
} ...
...
} else if (tid == typeid(Z)) {
Z * ptr = reinterpret_cast<Z*>(&msg);
}
}
据我所知,这段代码工作正常,正如我认为的那样。但是,我很好奇这是否只是因为我很幸运,或者这实际上是定义明确的用法吗?以这种方式使用 reinterpret_cast
。
在你说为此使用普通多态性之前,我无法按原样更改 classes,所以我需要围绕它构建这种方式。
不,行为在形式上仍未定义。
以这种方式使用 reinterpret_cast
仍然违反严格的别名规则。
如果性能 确实 是这里的一个问题,那么您可能希望完全避免 virtual
类。
与 Bathsheba 的回答一样,您仍然会有未定义的行为。
但是,如果你没有虚拟继承,你可以使用 static_cast
,这将正确偏移指向子 class 的指针:
void fn(Base & msg) {
const auto & tid = typeid(msg);
if (tid == typeid(A)) {
A * ptr = static_cast<A*>(&msg);
} else if (tid == typeid(B)) {
B * ptr = static_cast<B*>(&msg);
} else if (tid == typeid(Z)) {
Z * ptr = static_cast<Z*>(&msg);
}
}
如果我首先验证指向基 class 的指针属于某种类型(使用 typeid
),是否可以对其执行 reinterpret_cast
以节省一些性能?
class Base {
virtual ~Base() {}
};
class A : Base {};
class B : Base {};
...
class Z : Base {};
之后在某个地方:
void fn(Base & msg) {
const auto & tid = typeid(msg);
if (tid == typeid(A)) {
A * ptr = reinterpret_cast<A*>(&msg);
} else if (tid == typeid(B)) {
B * ptr = reinterpret_cast<B*>(&msg);
} ...
...
} else if (tid == typeid(Z)) {
Z * ptr = reinterpret_cast<Z*>(&msg);
}
}
据我所知,这段代码工作正常,正如我认为的那样。但是,我很好奇这是否只是因为我很幸运,或者这实际上是定义明确的用法吗?以这种方式使用 reinterpret_cast
。
在你说为此使用普通多态性之前,我无法按原样更改 classes,所以我需要围绕它构建这种方式。
不,行为在形式上仍未定义。
以这种方式使用 reinterpret_cast
仍然违反严格的别名规则。
如果性能 确实 是这里的一个问题,那么您可能希望完全避免 virtual
类。
与 Bathsheba 的回答一样,您仍然会有未定义的行为。
但是,如果你没有虚拟继承,你可以使用 static_cast
,这将正确偏移指向子 class 的指针:
void fn(Base & msg) {
const auto & tid = typeid(msg);
if (tid == typeid(A)) {
A * ptr = static_cast<A*>(&msg);
} else if (tid == typeid(B)) {
B * ptr = static_cast<B*>(&msg);
} else if (tid == typeid(Z)) {
Z * ptr = static_cast<Z*>(&msg);
}
}