2015-12-14 15 views
11

Jaki rodzaj rzutowania ma tu miejsce (w B::get())?Klasa pochodna od podstawy do podstawy

class A { 
public: 
    A() : a(0) {} 
    int a; 
}; 

class B : public A { 
public: 
    A* get() { 
     return this; //is this C-style cast? 
    } 
}; 

int main() 
{ 
    B b; 
    cout << b.get()->a << "\n"; 

    system("pause"); 
    return 0; 
} 

Widziałem tego rodzaju kod w słynnym API. Czy lepszą praktyką jest wykonywanie static_cast<A*>(this);?

+8

W ogóle nie ma rzucania, a jedynie niejawne nawrócenie. Gips to wyraźna konwersja. – molbdnilo

Odpowiedz

9

Jest to standardowa konwersja wskaźnika pochodnego na bazę. Zgodnie z regułami, wskaźnik D z pewnymi kwalifikacjami const/volatile można przekonwertować na wskaźnik na B z tymi samymi kwalifikatorami, jeśli B jest klasą podstawową z .

Standardowe konwersje są niejawnymi konwersjami z wbudowanymi znaczeniami i są oddzielnymi pojęciami od rzeczy takich jak static_cast lub rzutowania w stylu C.

W miarę możliwości najlepiej jest polegać na niejawnych konwersjach. Jawne konwersje powodują więcej zakłóceń kodu i mogą ukrywać błędy konserwacji.

+0

Ściśle, "można przekonwertować na wskaźnik na' B' z tym samym * lub więcej * kwalifikatorami " –

+2

Sugeruję konkretnie odpowiedzieć na jego pytanie:" Nie, nie lepiej jest używać 'static_cast' - w rzeczywistości jest to gorsza praktyka, zawsze unikaj rzutów, jeśli ich nie potrzebujesz. " –

+0

@MartinBonner Nie zgadzam się! Niejawne rzuty są źródłem wszelkiego rodzaju zwariowanych błędów. Czasem chciałbym, żeby C++ w ogóle ich nie miało ... Nic złego w byciu wyraźnym. – Barry

3

Jest to niejawna konwersja na przodka. Konwersje niejawne są generalnie bezpieczne i nie mogą robić rzeczy, których nie można wykonać. W rzeczywistości są one jeszcze bardziej ograniczone: można dokonać niezaznaczonego downcasta z static_cast, ale nie z niejawną konwersją.