Reputation: 43
I have a table of pointers to derived classes. The program uses a lot of small classes that use entries in those tables. Periodically, all those small classes have to be exchanged, with purpose that they use data in a different class in the table, but they only use the base class data. So those small classes use pointers to entries of the table, but those pointers are actually pointers to pointers to the base class. In isolation, it's this, and the below works in gcc 4.8.2 (the real thing has complex classes; this is just an example)
#include <iostream>
class Base {public: int i;};
class Derived : public Base {public: int j;};
int main() {
Base **b;
Derived *table[2];
table[0] = new Derived; table[0]->i = 1; table[0]->j = -2;
table[1] = new Derived; table[1]->i = 4; table[1]->j = -5;
b = reinterpret_cast<Base**>(&(table[0]));
std::cout << "first: " << (**b).i << " " << "\n";
b = reinterpret_cast<Base**>(&(table[1]));
std::cout << "second: " << (**b).i << " " << "\n";
{Derived *temp; temp = table[0]; table[0] = table[1]; table[1] = temp;}
b = reinterpret_cast<Base**>(&(table[0]));
std::cout << "first switched: " << (**b).i << " " << "\n";
b = reinterpret_cast<Base**>(&(table[1]));
std::cout << "second switched: " << (**b).i << " " << "\n";
}
There is no way that the table can ever get corrupted: it always will contain pointers all to exactly the same derived class type, so in theory they can all be exchanged. The classes that use the table will only ever use base class data. If reinterpret_cast
is replaced by either dynamic_cast
or static_cast
then the compiler complains. Now, this is all fine, except for admonitions like this: "...which on most cases results in code which is system-specific, and thus non-portable", and other really scary and severe statements by opinionated experts who obviously know a lot.
Is the above a reasonable and safe use of reinterpret_cast?
Upvotes: 0
Views: 97
Reputation: 101456
Neither safe nor reasonable.
First a bit of a rant. reinterpret_cast
is a broadswoard. A weapon of last resort. It is not safe. It is not friendly. It will not protect you from yourself. It should not be your go-to tool of choice. You should not just bang reinterpret_cast
in there if static_cast
doesn't "work" and you don't understand what the compiler is telling you. Instead, you should first try to understand the compiler's error messages, and then fix the actual problem.
End of rant. Now in your case:
b = reinterpret_cast<Base**>(&(table[0]));
table
is an array of pointer-to-Derived
. So you are trying to cast from a pointer-to-pointer-to-Derived
to a pointer-to-pointer-to-Base
. What you should do instead is cast a pointer-to-Derived
to pointer-to-Base
, like this:
Base* b = static_cast<Base*>(table[0]);
And then use it:
std::cout << "first: " << (*b).i << " " << "\n";
But since Derived
is a direct descendant of Base
, you don't even need an explicit cast. This would work just fine:
Base* b = table [0];
Even better still, since you don't really need a pointer, why not just grab a reference instead?
Base& b = *table[0];
std::cout << "first: " << b.i << " " << "\n";
Upvotes: 4