2015-10-28 27 views
5

Powiedzmy mam trzy klasy: A (matka, streszczenie), a B i C, dzieci A.niejawna konwersja vs. static_cast gdy upcasting

Tak B i C dziedziczą od A (dziedziczenie publiczne) . Mam listę wskaźników do A, które zapełniam wskaźnikami B lub C.

Pytanie brzmi: jaki jest preferowany styl podczas wykonywania rzutowania/konwersji?

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

Czyli pod względem klarowności (stylu kodowania) i bezpieczeństwa, który z nich jest lepszy? Rozumiem, że static_cast jest łatwiejszy do wyszukania, ale w tym przypadku niejawna konwersja powinna wystarczyć.

Odpowiedz

7

Nie musisz do static_cast do klasy podstawowej, static_cast jest iść w przeciwnym kierunku. Tak to jest w porządku

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

Czas musiałbyś static_cast jest zrobić coś oddające A* do klasy pochodnej B*

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

Oto odpowiedź, której potrzebowałem. Więc nie static_cast podczas upcasting, ale tak, gdy downcasting. Dziękuję Ci! (i bardzo szybka odpowiedź!) – fern17

+1

@ fern17 Zwróć też uwagę, że przy downcastingu możesz nie zawsze wiedzieć, czy jest to B czy C. To właśnie dotyczy 'dynamic_cast'. – JorenHeit

+0

Tak, wiem, dziękuję za wyjaśnienie (dla przyszłości mnie, kto powróci na to pytanie) – fern17

0

Chciałbym rozszerzyć na odpowiedź udzieloną już z bardzo ogólne rozwiązanie.

Nigdy nie należy jawnie rzutować tego, co kompilator już niejawnie rzuci za Ciebie.

Możemy nawet uogólnić ten dalej:

Ludzie popełniają błędy. Nigdy wyraźnie nie rób tego, co kompilator już dla ciebie zrobi.

... choć może to być nieco bardziej dyskusyjne w niektórych bardzo niejasnych wyjątkowych przypadkach. Poprzednie zdanie powinno zawsze być prawdziwe.

Jednoznaczne rzucanie w niepotrzebny sposób narusza zasadę DRY i, co ważniejsze, zapraszanie ludzi do błędów i pomyłek w przyszłości.

Dlatego należy unikać rzutowania wszystkiego, co nie jest wymagane. Wyraźne rzuty są bronią: obnosić się z nimi niepotrzebnie zbyt często i ktoś musi zostać zraniony.