4

I have two classes, A, and B. A is a parent class of B, and I have a function that takes in a pointer to a class of type A, checks if it is also of type B, and if so will call another function that takes in a pointer to a class of type B. When the function calls the other function, I supply reinterpret_cast(a) as the parameter. If this seems ambiguous here is a code example:

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));
  };
};

So now that you know how I am calling "def", I am wondering if reinterpret_cast actually returns a pointer of type B to be sent off as the parameter to def. I would appreciate any help. Thanks

mike bayko
  • 375
  • 5
  • 20

5 Answers5

5

reinterpret_cast will always do what you say - it is a sledghammer. You can do

def(reinterpret_cast<B *>(42));

or

std::string hw = "hello";
def(reinterpret_cast<B *>(hw));

it will always return a pointer that might point at the correct type. It assumes you know what you are doing

pm100
  • 48,078
  • 23
  • 82
  • 145
3

You will have a pointer of type B*, but reinterpret_cast isn't really great.

If you're sure the type is a B, use static_cast, if not, use dynamic_cast and test the pointer (if dynamic_cast fails, it returns nullptr)

See https://stackoverflow.com/a/332086/5303336

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Random Coder 99
  • 376
  • 1
  • 15
2

reinterpret_cast is the result of a broken type system. Its behaviour assumes that there is a union such as

 union { 
     TypeA anA;
     TypeB aB;
 } a;

so

 reinterpret_cast< B* >( a );

Assumes a is pointer to member anA and can then deliver the aB address.

If the type is part of the same class hierarchy, then static_cast<> would allow you to find out at compile time if there was enough information to perform the cast. This is generally when B is a base class of A (either singly or multiply).

If there is insufficient information for static_cast to work, then it may be possible to get a dynamic_cast<> to work. This is the case where the B type is derived in some way from A.

It is important to note that the dynamic_cast<B*>( a ) or static_cast< B*>( a ) may not yield the same address when they succeed.

That is because when multiply inherited, the secondary inheritance creates multiple classes and vtables in the object. When this happens, the static_cast, dynamic_cast adjust the base address of the object to find the correct embedded class base address.

The fact that dynamic_cast and static_cast may change the address, is why reinterpret_cast is discouraged. It can result in a value which doesn't do what you want.

mksteve
  • 12,614
  • 3
  • 28
  • 50
1

Reinterpret cast will always return a pointer. It may just not be a valid pointer in the sense that it actually points to an object of type B.

If B has more than one base class, and A is not the first base class, reinterpret cast will do the wrong thing and fail to perform necessary adjustment to the pointer.

For your usecase you should use a static cast which has the advantage that the compiler will check whether B is actually derived from A and perform any needed adjustment. No runtime overhead is incurred by additional checks, however there will be no warning if the object is not actually of type B and the program will fail arbitrarily.

PaulR
  • 3,587
  • 14
  • 24
1

As others have stated, reinterpret_cast is the wrong solution, use dynamic_cast instead:

void abc(A * a) {
    B *b = dynamic_cast<B*>(a);
    if (b) {
        def(b);
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770