2010-10-06 12 views
6

Angenommen, ich habe eine Klasse mit dem Namen Base und eine Klasse, die davon abgeleitet ist SuperBase genannt. Da add nimmt in einem Base*, würde entweder davon gültig:Casting zur Basis Klassengültigkeit

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

Oder

SuperBase *super = new SuperBase; 
bases.add((Base*)super); 
+0

Ich kann nicht einen guten Titel für die Frage denken, aber ich denke, das ist besser. – GManNickG

Antwort

9

die ersten Werke, solange SuperBase leitet sich öffentlich von Base über eine implizite Konvertierung von abgeleiteten zu -Basis:

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

base* b = new derived; // okay 

die zweite Werk auch ignoriert aber den Schutz der Base:

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

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

Wenn es private ist, sollten Sie wahrscheinlich nicht darauf werfen.

+1

+1 für undefiniertes Verhalten – jmasterx

+0

Verwenden Sie 'static_cast ' statt einer C-Stil-Umwandlung '(Base *)', um sicherzustellen, dass Sie nicht mit undefiniertem Verhalten zu tun haben. –

+2

Aber das stimmt nicht! (Zumindest in C++ 03). C-Style-Cast auf eine unzugängliche Base * ist * garantiert, um korrekt zu funktionieren (d. H. Als ob die Base zugänglich wäre). Der resultierende Zeiger ist ein gültiger Zeiger auf das Basisklassen-Unterobjekt vom Typ "Base" und kann sicher als solcher verwendet werden. I.e. C-Style-Cast ist in diesem Fall kein 'reininterpret_cast', sondern ein' static_cast', der den Schutz ignoriert. Es ist natürlich immer noch eine schlechte Programmierpraxis, da es den Schutz ignoriert, aber es "funktioniert". Warum sagst du, dass das Verhalten nicht definiert ist? – AnT

1

Beide sind gültig - ein Kind kann an einem Ort verwendet werden, an dem ein Verweis/Zeiger auf den Elternteil erwartet wird. Dies nennt man Polymorphismus.

1

Beide wären gültig, obwohl Typ-Casting super zu Base* nicht notwendig ist.