Niedawno znalazłem świetny przykład, dlaczego rzuty w stylu C są złe. Zaczynamy następnym klasa implementująca wiele interfejsów COM (mam dwie dla zwięzłości, ale nie może być dziesięć w prawdziwym życiu):Jakie przykładowe przykłady sĘ ... tam pokazywane rzuty w stylu C sĘ ... złe?
class CMyClassInitial : public IInterface1, public IInterface2 {
//declarations omitted
};
HRESULT CMyClassInitial::QueryInterface(REFIID iid, void** ppv)
{
if(ppv == 0) {
return E_POINTER;
}
*ppv = 0;
if(iid == __uuidof(IUnknown) || iid == __uuidof(IInterface1)) {
*ppv = (IInterface1*)this;
} else if(iid == __uuidof(IInterface2)) {
*ppv = (IInterface2*)this;
} else {
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
Powyższa implementacja wykorzystuje C-odlewane dla adjusting pointers to account for multiple inheritance. Działają nawet tak, jakby wartość wskaźnika została odpowiednio dostosowana.
Teraz kopiuj-wklej (lub powinienem powiedzieć ponowne wykorzystanie kodu z?) Ta sama QueryInterface()
wdrożenie do innego bardzo podobnej klasy.
class CMyClassModified : public IInterface1 {
//declarations omitted
};
i pozostawić wdrożenie tak samo. Nowa klasa nie dziedziczy z IInterface2
już jednak
} else if(iid == __uuidof(IInterface2)) {
*ppv = (IInterface2*)this;
}
skompiluje dobrze i C-style cast będzie działać jako reinterpret_cast
- this
wartość wskaźnika zostaną skopiowane bez zmian. Osoba dzwoniąca uzyska wskaźnik do obiektu, który w rzeczywistości nie implementuje IInterface2
- prosto do niezdefiniowanego zachowania. Takie problemy mogą być trudne do wykrycia w ogromnej bazie danych i gdy istnieje wiele (nie dwa, jak w moim przykładzie) interfejsów.
Jeśli static_cast
użyto że by się nie stało - kompilator będzie emitować błąd próbuje skompilować
*ppv = static_cast<IInterface2*>(this);
IMO to jest wystarczająco ostry przykład jak za pomocą odlewane stylu C może spowodować poważne problemy.
Jakie są inne przykłady?
Wielki haczyka, ale nie jestem całkowicie pewien, że to nadaje się do SO. Wydaje się bardzo dyskusyjny. W najlepszym razie jest to wiki społeczności. – tenpn
@tenpn: Nie widzę, co można tutaj omówić - tylko przykład strzelania sobie w nogę w C++. – sharptooth
@ Sharppt, ale to nie jest pytanie, prawda? – tenpn