jayatubi
jayatubi

Reputation: 2202

In C++ how could I cast a sub class instance from one base class pointer to another without dynamic_cast?

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

Answers (3)

Walter
Walter

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

David Haim
David Haim

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

TartanLlama
TartanLlama

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

Related Questions