2010-03-28 11 views
11

Odnośnie poniższego program w C++:Konwersja wskaźnika do wskaźnika między klasą pochodną i klasą podstawową?

class Base { }; 

class Child : public Base { }; 

int main() 
{ 
    // Normal: using child as base is allowed 
    Child *c = new Child(); 
    Base *b = c; 

    // Double pointers: apparently can't use Child** as Base** 
    Child **cc = &c; 
    Base **bb = cc; 

    return 0; 
} 

GCC produkuje następujący błąd na ostatniej instrukcji przypisania:

error: invalid conversion from ‘Child**’ to ‘Base**’ 

moje pytanie jest na dwie części:

  1. dlaczego nie ma niejawna konwersja z Child ** do Base **?
  2. Mogę sprawić, aby ten przykład działał z obsadą w stylu C lub reinterpret_cast. Używanie tych odlewów oznacza wyrzucenie wszelkiego rodzaju bezpieczeństwa. Czy jest coś, co mogę dodać do definicji klas, aby te wskaźniki były domyślnie rzucane, lub przynajmniej wyrażały konwersję w sposób, który pozwala mi używać zamiast tego static_cast?
+0

Wariacje na temat tego pytania w wielu językach programowania są jednym z najczęściej zadawanych pytań dotyczących SO. Ale wszyscy określają to nieco inaczej, nawet dla tego samego języka, więc znalezienie duplikatów może być trudne. –

+0

"Naprawianie" tego przykładu, aby uniknąć podejrzanych rzutów, zależy od tego, dlaczego najpierw używasz wskaźnika do wskaźnika. – aschepler

Odpowiedz

19

Jeśli to było dozwolone, można napisać to:

*bb = new Base; 

I c skończy się wskazując na wystąpienie Base. Zły.

+0

Mała korekta - mógł powiedzieć: '** bb = new Base();' Po prostu '* bb' nie byłoby dozwolone. – Phil

+4

@Phil: 'new' zwraca wskaźnik, który jest typu' * Baza'. 'bb' jest typu' ** Base'. Zatem '* bb' to właściwy poziom dereferencji. – Amber

+1

Uzasadnienie jest zasadniczo takie samo jak w comp.lan.gc Najczęściej zadawane pytania dotyczące braku równoważności "char **" i "char const **": http://c-faq.com/ansi/constmismatch.html –

Powiązane problemy