11

Let's say I have three classes: A (the mother, abstract), and B and C, the children of A.

So B and C inherit from A (public inheritance). I have a list of pointers to A, which I populate with pointers of B or C.

The question is: which is the preferred style when doing the casting/conversion?

class A {};
class B : public A {};
class C : public A {};

B* objB = new B();
C* objC = new C();

std::list<A*> myList;
// Option A: static cast conversion
myList.push_back(static_cast<A*> (objB));
myList.push_back(static_cast<A*> (objC));

// Option B: implicit conversion
myList.push_back(objB);
myList.push_back(objC);

// Option C: C-style conversion (I understand that this is evil and must be avoided)
myList.push_back((A*) objB);
myList.push_back((A*) objC);

So, in terms of clarity (code style) and in terms of safety, which one is better? I understand that static_cast is easier to search for, but on this case, an implicit conversion should be enough.

m.s.
  • 16,063
  • 7
  • 53
  • 88
fern17
  • 467
  • 6
  • 20

2 Answers2

12

You don't have to static_cast to the base class, the static_cast is to go the other direction. So this is fine

myList.push_back(objB);
myList.push_back(objC);

The time you'd have to static_cast is to do something casting an A* to a derived class B*

B* some_obj = static_cast<B*>(myList.front());
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • This is the answer I needed. So no static_cast when upcasting, but yes when downcasting. Thank you! (and a very fast answer!) – fern17 Oct 28 '15 at 13:01
  • 2
    @fern17 Also, note that when downcasting, you might not always know if it's a B or C. That's what `dynamic_cast` is for. – JorenHeit Oct 28 '15 at 14:21
  • 1
    Yes, I know, thank you for make it explicit (for the future me who will return to this question) – fern17 Oct 28 '15 at 15:30
1

I'd like to extend on the answer provided already with a very general solution.

Never explicitly cast what the compiler will already implicitly cast for you.

We might even generalize this further to:

Humans make mistakes. Never explicitly do what the compiler will already do for you.

... though that might be a little more debatable in some very obscure exceptional cases. The previous sentence should always hold true.

To explicitly cast superfluously is just violating the DRY principle and, more importantly, inviting human error and confusion in the future.

So avoid explicitly casting anything that doesn't require it. Explicit casts are a weapon: flaunt them unnecessarily too often and someone's bound to get hurt.