Thursday, May 5, 2011

Virtual inheritance in C++

Часто встречал вопрос на эту тему. Ответ что это и как работает, как бы намекает, что человек как минимум внимательно читает книги (т.к. большинство людей этот вид наследования не используют). Обычно ответ такой: нужно чтоб избежать двух копий базового класса при «ромбовидном» наследовании.
Обычно на этом всё заканчивается – мол, молодец (читаешь внимательно).
Но вопросы нужно продолжить. Например:
– Что если не использовать виртуальное наследование в данном случае? Как тогда?
О:…
– Во всех ли случаях этот вид наследования нужен, если нет, то в каких?
О: Если нет дублирования данных, только функции – то в принципе это дублирование никому не мешает.
– В MS COM есть базовый класс IUnknown, и есть дальше почти всегда «ромбовидное» наследование, но виртуальность тут не используется, почему?
О: Бинарный стандарт COM требует такую структуру в памяти, где у каждого есть своя копия таблицы IUnknown.
– Как выглядит это в памяти, и что со скоростью?
О: ESC_Boston_01_304_paper, страница 19.

Далее после этих вопросов, можно спросить, а зачем вообще нужно наследование? Что делать если его нет? Хорошо или плохо его использовать, почему, когда, где? Очень болезненная тема для многих. Часто в проекте получается, типа один говорит «Не трогайте мои классы/мою архитектуру!», а ему в ответ «OOP must Go!». Вот в тему очень полезная статья/блог: avoiding inheritance dependency

4 comments:

  1. >Если нет дублирования данных, только функции –
    >то в принципе это дублирование никому не мешает

    почему же? а какой метод будет вызываться тогда? как определить? больше бы инфы, эх...

    ReplyDelete
  2. @0lg3rd

    Если будут только функции, то прийдется делать некрасивые касты чтоб работало. Да, это плохо, но можно. А если будут не только функции а и данные - то тогда данные в зависимости от того куда кастить будут лежать в разной памяти. ( т.е. методы класса в отличии от данных не меняют своего состояния, и поэтому всё равно через какой каст к ним обращатся ).
    Вот полезная еще ссылка: http://www.parashift.com/c++-faq-lite/multiple-inheritance.html с пункта 25.8.

    ReplyDelete
  3. Ооо ужас, я явно отстал от жизни =))
    Тимоха, а как же наш Begin End. с точкой в конце? куда это все делось =))) где те временна процедурные?

    ReplyDelete