Reputation: 2202
I want to do this without 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?
}
I think the instance of type ClassC
could represent as both ClassA
and ClassB
. Now if I could only get the pointer in the type of ClassA
how can I cast it into ClassB
without dynamic_cast
?
Upvotes: 3
Views: 160
Reputation: 45424
In well designed code, this type of problem should hardly ever occur. So, better rethink your design. Perhaps you want to avoid polymorphism, when you really should use it? You could
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();
-- effectively implementing a more efficient way of dynamic cast.
Upvotes: 4
Reputation: 26486
You can use some casts to cast pClassA
into B*
, including reinterpret_cast
and C-style casts.
Your real question is "How can I cast it safely without dynamic_cast
. Well, although you can do all kind of object-validation mechanisms, I doubt that you really need them.
what is wrong with dynamic_cast
?
Edit: hmmm. I prefer Idiomatic C++ over tricks but there are times where you do need the raw size/speed. I would go with some marking mechanism:
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 ; }
};
this way you statically ask if the object is from the type Types
real run: http://coliru.stacked-crooked.com/a/1774f9c85603fa31
Upvotes: 1
Reputation: 65620
A
and B
are unrelated types, so you can't just cast between them. So long as you are certain that pClassA
points to a C
, you can do an intermediate cast to C*
, then rely on implicit derived-to-base conversions to get to B*
:
B* pClassB = static_cast<C*>(pClassA);
Or you can explicitly cast through C*
to B*
:
B* pClassB = static_cast<B*>(static_cast<C*>(pClassA));
Upvotes: 5