2010-03-28 7 views
11

Что касается следующей программы на C++:Преобразование указателя в указатель между производными и базовыми классами?

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 производит следующую ошибку на последнем операторе присваивания:

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

Мой вопрос состоит из двух частей:

  1. Почему нет неявное преобразование из Ребенка ** в базу **?
  2. Я могу сделать этот пример работы с литым стилем C или reinterpret_cast. Использование этих отливок означает выброс всех типов безопасности. Есть ли что-нибудь, что я могу добавить к определениям классов, чтобы сделать эти указатели неявно или, по крайней мере, фразой преобразования таким образом, чтобы вместо этого использовать static_cast?
+0

Вариации по этому вопросу на многих языках программирования являются одним из наиболее распространенных вопросов о SO. Но все фразы это немного по-разному даже для одного и того же языка, поэтому найти дубликаты могут быть трудными. –

+0

«Исправление» этого примера, чтобы избежать теневых бросков, будет зависеть от того, почему вы используете указатель на указатель в первую очередь. – aschepler

ответ

19

Если это было разрешено, вы могли бы написать это:

*bb = new Base; 

И c бы в конечном итоге указывает на экземпляр Base. Плохо.

+0

Небольшая коррекция - он мог бы сказать '** bb = new Base();' Just '* bb' не разрешалось. – Phil

+4

@Phil: 'new' возвращает указатель, который является типом' * Base'. 'bb' имеет тип' ** Base'. Таким образом, '* bb' является правильным уровнем разыменования. – Amber

+1

Обоснование по существу то же самое, что и comp.lan.gc FAQ о неэквивалентности 'char **' и 'char const **': http://c-faq.com/ansi/constmismatch.html –

 Смежные вопросы

  • Нет связанных вопросов^_^