2015-10-28 21 views
5

Sagen wir, ich habe drei Klassen: A (die Mutter, abstrakt) und B und C, die Kinder von A.Implizite Konvertierung vs. static_cast wenn Upcasting

So B und C erben von A (öffentliche Vererbung) . Ich habe eine Liste von Zeigern zu A, die ich mit Zeigern von B oder C bevölkert.

Die Frage ist: Welches ist der bevorzugte Stil beim Casting/Konvertierung?

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

Also, in Bezug auf die Klarheit (Code-Stil) und in Bezug auf die Sicherheit, welche ist besser? Ich verstehe, dass static_cast einfacher zu suchen ist, aber in diesem Fall sollte eine implizite Konvertierung ausreichen.

Antwort

7

Sie müssen nicht static_cast zu der Basisklasse, die static_cast ist die andere Richtung gehen. So ist dieses feine

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

Die Zeit, die du static_cast haben würde, ist, etwas zu tun, um eine A* auf eine abgeleitete Klasse Gießen B*

B* some_obj = static_cast<B*>(myList.front()); 
+0

Dies ist die Antwort, die ich brauchte. Also kein static_cast beim upcasting, sondern ja beim downcasting. Vielen Dank! (und eine sehr schnelle Antwort!) – fern17

+1

@ fern17 Beachten Sie auch, dass Sie beim Downcasting möglicherweise nicht immer wissen, ob es ein B oder C ist. Dafür steht 'dynamic_cast'. – JorenHeit

+0

Ja, ich weiß, danke, dass du es ausdrückst (für die Zukunft werde ich auf diese Frage zurückkommen) – fern17

0

Ich mag würde auf die Antwort erstrecken bereits mit eine sehr allgemeine Lösung.

Niemals explizit ausdrücken, was der Compiler bereits implizit für Sie darstellen wird.

Wir könnten sogar verallgemeinern weiter:

Menschen machen Fehler. Tue niemals explizit, was der Compiler für dich tun wird.

... obwohl das in einigen sehr obskuren Ausnahmefällen etwas strittiger sein könnte. Der vorherige Satz sollte immer wahr sein.

Explizit überflüssig zu sein, verstößt nur gegen das DRY-Prinzip und, was noch wichtiger ist, lädt in Zukunft menschliche Fehler und Verwirrung ein.

Also vermeiden Sie es, explizit etwas zu werfen, das es nicht benötigt. Explizite Zaubersprüche sind eine Waffe: Sie müssen sie unnötigerweise zu oft zur Schau stellen und jemand wird verletzt.