我想在没有dynamic_cast
的情况下执行此操作:
class A {};
class B {};
class C : public A, public B {};
void func()
{
A* pClassA = new C();
B* pClassB = what_cast<B*>(pClassA); // what could the cast be?
}
我认为ClassC
类型的实例可以同时代表ClassA
和ClassB
。现在,如果我只能获得ClassA
类型的指针,如何在没有ClassB
的情况下将其转换为dynamic_cast
?
答案 0 :(得分:5)
A
和B
是不相关的类型,因此您无法在它们之间进行投射。只要您某些 pClassA
指向C
,您就可以对C*
进行中间转换,然后依赖隐式派生到基础转换到B*
:
B* pClassB = static_cast<C*>(pClassA);
或者您可以明确地将C*
强制转换为B*
:
B* pClassB = static_cast<B*>(static_cast<C*>(pClassA));
答案 1 :(得分:4)
在设计良好的代码中,几乎不会发生这种类型的问题。所以,更好地重新思考你的设计。也许你想要避免多态,当你真的应该使用它?你可以
struct B; // forward decl
struct A {
virtual B*this_as_B_ptr() { return nullptr; }
const B*this_as_B_ptr() const { return const_cast<A*>(this)->this_as_B_ptr(); }
virtual~A() {}
};
struct B { /* ... */ }; // may be in different header
struct C:A,B // may be in yet different header
{
B*this_as_B_ptr() override { return this; }
};
A* pA = new C;
B* pB = pA->this_as_B_ptr();
- 有效实施更有效的动态投射方式。
答案 2 :(得分:1)
您可以使用某些演员阵容将pClassA
投射到B*
,包括reinterpret_cast
和C风格演员阵容。
你真正的问题是&#34;如何在没有dynamic_cast
的情况下安全地 。好吧,虽然你可以做各种对象验证机制,但我怀疑你真的需要它们。
dynamic_cast
出了什么问题?
<强> 编辑: 强> 嗯。我更喜欢Idiomatic C ++而不是技巧,但有时你确实需要原始大小/速度。我会选择一些标记机制:
enum Types{AType,BType,CType};
struct A {
int type;
A(): type(AType) {}
bool is (Types wantedType) {return (type & wantedType) == wantedType; }
};
struct B {
};
struct C : public A, public B {
C(){ type = (type | CType) | BType ; }
};
通过这种方式,您可以静态询问对象是否来自类型Types