views:

77

answers:

3

Say I have a class named Base and a class that derives from it called SuperBase. Given that add takes in a Base*, would either of these be valid:

SuperBase *super = new SuperBase;
bases.add(super);

Or

SuperBase *super = new SuperBase;
bases.add((Base*)super);
+7  A: 

The first works as long as SuperBase publicly derives from Base, via an implicit conversion from derived-to-base:

struct base { virtual ~base() {} };
struct derived : base {};

base* b = new derived; // okay

The second works as well, but ignores the protection of Base:

struct derived : private base {}; // private base

base* b = new derived; // not okay, base is private
base* b = (base*)(new derived); // okay, but gross

If it's private, you probably shouldn't cast to it.

GMan
+1 for undefined behavior
Milo
use `static_cast<Base*>` instead of a C-style cast `(Base*)` to make sure you are not dealing with undefined behavior.
Alex Emelianov
@GMan: But that's not true! (At least in C++03). C-style cast to an inaccessible base *is* guaranteed to work correctly (i.e. as if the base were accessible). The resultant pointer is a valid pointer to the base-class sub-object of type `Base` and it can be safely used as such. I.e. C-style cast is not a `reinterpret_cast` in this case, but rather a `static_cast` that ignores protection. It is, of course, still a bad programming practice, since it ignores protection, but it "works". Why do you say the behavior is undefined?
AndreyT
@Andrey: Oooh, I'm just flat out wrong then. I thought it acted exactly like `reinterpret_cast`. Fixed, thanks. @Milo: Forget I said that, it's wrong.
GMan
+1  A: 

Both are valid - a child can be used in a place where a reference/pointer to parent is expected. This is called polymorphism.

dark_charlie
+1  A: 

Both would be valid, though type-casting super to Base* is not necessary.

Remy Lebeau - TeamB