Виртуальное наследование
От: Kudinov Alexander Россия http://www.devdoc.ru
Дата: 04.09.07 05:01
Оценка: 1 (1)
Добрый день!

Я опубликовал черновой вариант статьи на http://www.devdoc.ru/index.php/content/view/virtual_inheritance.htm про виртуальное наследование. В ней дан обзор множественному наследованию в целом, а также разобраны внутренности работы виртуального наследования.

Мне было бы интересно услышать мнение спецов по содержанию статьи. Как всегда конструктивные комментарии приветсвуються.

--
Кудинов Алексндр,
www.devdoc.ru — Статьи по программированию
--
Александр.

http://www.devdoc.ru. – новые статьи по программированию каждую неделю.
Re: Виртуальное наследование
От: MasterZiv СССР  
Дата: 04.09.07 09:50
Оценка: +1
Kudinov Alexander пишет:

В первом случае – мы будем использовать только одну из копий объекта A. Вторая
копия у нас просто «повиснет» и программа в целом может работать неверно, т.к.
класс B ничего не знает о том, что его предок не используется. Т.е. вторая копия
подобъекта A никак не будет использоваться, но будет занимать память. Во втором
варианте – просто выполняется дублирование операций, и как следствие возникает
необходимость поддерживать синхронность обоих подобъектов типа A. Это плохой
стиль и рассадник всевозможных ошибок.


Эти рассуждения вне контекста конкретной иерархии классов и ее функциональности
бессмысленны. Тем не менее выводы довольно категоричны и однозначты.

А в остальном вроде как и ничего...
Posted via RSDN NNTP Server 2.1 beta
Re: Виртуальное наследование
От: Аноним  
Дата: 06.09.07 17:00
Оценка: +1
Здравствуйте, Kudinov Alexander

Кстати про виртуальное наследование:
давно интересуют примеры его использования в реальных программах.
Пока единственное, что я видел — это пример из STL:
template <class Elem, class Tr = char_traits<Elem> >
   class basic_istream
      : virtual public basic_ios<Elem, Tr>

Так же на форуме приводился пример со счётчиком экземпляров класса.
Честно говоря, создаётся впечатление, что это очень сомнительная фича C++...
Re[2]: Виртуальное наследование
От: Programador  
Дата: 06.09.07 20:36
Оценка: -1
Здравствуйте, Аноним, Вы писали:
А>Так же на форуме приводился пример со счётчиком экземпляров класса.
А>Честно говоря, создаётся впечатление, что это очень сомнительная фича C++...
Если есть множественное наследование, то должно быть и виртуальное. А зачем нужно множественное? да затем что и простое.
Кстати и без простого можно и обойтись
struct B
{ int x,y;
};
struct D
{ B B;
  int z;
};
Re[3]: Виртуальное наследование
От: McSeem2 США http://www.antigrain.com
Дата: 07.09.07 00:43
Оценка: 6 (1) +4
Здравствуйте, Programador, Вы писали:

P>Если есть множественное наследование, то должно быть и виртуальное. А зачем нужно множественное? да затем что и простое.

P>Кстати и без простого можно и обойтись
P>
P>struct B
P>{ int x,y;
P>};
P>struct D
P>{ B B;
P>  int z;
P>};
P>


Без наследования можно обойтись. И даже нужно, полностью сохраняя при этом идею полиморфизма. Но не в C++, Java, C# и тому подобных. Сама идея наследования как расширения функциональности является глубоко порочной и противоречит сущности нашего мира. Особенный LOL вызывают попытки порождения производных классов от std::string, std::vector<MyType> и тому подобных. Наследование должно быть только специализацией функциональности и ничем более. Короче, нет виртуальных функций в базовом классе? — наследование запрещено. Вот так должно быть IMSO. Но тогда это уже и не наследование получается, а некая динамическая специализация. А тот беспредел, что сейчас имеется, в конечном итоге приводит к обилию нелепых конструкций, типа ((my_string*)&std_str)->my_compare_with(b);
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[4]: Виртуальное наследование
От: Erop Россия  
Дата: 07.09.07 06:33
Оценка: -2
Здравствуйте, McSeem2, Вы писали:

MS>Сама идея наследования как расширения функциональности является глубоко порочной и противоречит сущности нашего мира.

А как же ООП иерархии?
Скажем такая:
предмет мебели
 предмет мебели, на котором сидят
  кресло


MS>Но тогда это уже и не наследование получается, а некая динамическая специализация. А тот беспредел, что сейчас имеется, в конечном итоге приводит к обилию нелепых конструкций, типа ((my_string*)&std_str)->my_compare_with(b);

А может лучше научиться нормально программировать? Хотя я согласен, что в функциональном языке наследование смотрится чужеродно. Ну так ведь C++ он же мультипарадигменный, или как там это зовут нынче?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Виртуальное наследование
От: McSeem2 США http://www.antigrain.com
Дата: 07.09.07 16:46
Оценка: 1 (1)
Здравствуйте, Erop, Вы писали:

E>А как же ООП иерархии?

E>Скажем такая:
E>
E>предмет мебели
E> предмет мебели, на котором сидят
E>  кресло
E>


Ясно же было сказано — если нет необходимости в использовании витруальных функций, то нет и ни малейшего смысла в этой иерархии.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[6]: Виртуальное наследование
От: Erop Россия  
Дата: 07.09.07 18:12
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Ясно же было сказано — если нет необходимости в использовании витруальных функций, то нет и ни малейшего смысла в этой иерархии.


Да? А почему? Почему я не могу, например, иметь список предметов мебели в комнате, особенно если у каждого из них прописан тип, в виде аттрибута?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Виртуальное наследование
От: Roman Odaisky Украина  
Дата: 08.09.07 09:27
Оценка: 5 (2)
Здравствуйте, Аноним, Вы писали:

А>Кстати про виртуальное наследование:

А>давно интересуют примеры его использования в реальных программах.

Есть вот такой баян, запрещающий наследование от определенного класса:
class Final;

class FinalHelper
{
friend class Final;
private:
    FinalHelper() { }
};

class Final: public SomeInterface, virtual private FinalHelper
{
    . . .
};

class Error: public Final // не-не
{
    . . .
};

Здесь конструктор FinalHelper должен будет быть вызван из конструктора Error (если бы наследование было невиртуальным, этот конструктор вызывался бы из конструктора Final), а Error не имеет к нему доступа, потому что он private.
До последнего не верил в пирамиду Лебедева.
Re[4]: Виртуальное наследование
От: Evgeniy13 Россия  
Дата: 08.09.07 12:09
Оценка: 4 (1) -1
Здравствуйте, McSeem2, Вы писали:

MS>Без наследования можно обойтись. И даже нужно, полностью сохраняя при этом идею полиморфизма. Но не в C++, Java, C# и тому подобных. Сама идея наследования как расширения функциональности является глубоко порочной и противоречит сущности нашего мира. Особенный LOL вызывают попытки порождения производных классов от std::string, std::vector<MyType> и тому подобных. Наследование должно быть только специализацией функциональности и ничем более. Короче, нет виртуальных функций в базовом классе? — наследование запрещено. Вот так должно быть IMSO. Но тогда это уже и не наследование получается, а некая динамическая специализация. А тот беспредел, что сейчас имеется, в конечном итоге приводит к обилию нелепых конструкций, типа ((my_string*)&std_str)->my_compare_with(b);


Полностью согласен.
Хотя есть все-таки несколько исключений из этого правила:
— Наследование вместо агрегации (не нужно лишний раз обращаться к переменной). Но в этом случае очевидно должно быть защищенное наследование.
— Наследование как наследования реализации (опять-таки должно быть защищенное наследование)
— Наследование при всяких С++ "штучках" (например при реализации стратегий или статического полиморфизма)
Не все в этом мире можно выразить с помощью нулей и единиц...
Re[4]: Виртуальное наследование
От: Programador  
Дата: 08.09.07 17:42
Оценка: -1 :)
Здравствуйте, McSeem2, Вы писали:

MS> Сама идея наследования как расширения функциональности является глубоко порочной и противоречит сущности нашего мира.

В окружающем мире нет сущностей, В нем нет мебели, есть конкретные стулья, кресла. В некотором месте программы можно таскать мышкой нечто имеющее x y z и w h l и это вобщем удобно иначе программы вообще невозможно былобы писать. Креслу не обязательно менять чтото в паралелепипеде, а паралелепипеду знать что на нем можно сидеть

MS>Короче, нет виртуальных функций в базовом классе? — наследование запрещено. Вот так должно быть IMSO.

Это удобная схема в которую многое укладывается. Но к сожалению не все. У нас помимо мебели есть оружие, инвентору, точка в пространстве окуда появляются черти и т.д. и некоторые опрерации для этих предметов общие, например — подвергнуть заклинанию, произвести цикл обновления, записать, отрисовать. Но при этом сущности настолько разные, что неразумно их включать в одну иерархию. Иначе это получится некий универсальный суперпредок.
Re[7]: Виртуальное наследование
От: McSeem2 США http://www.antigrain.com
Дата: 08.09.07 19:23
Оценка: 6 (1)
Здравствуйте, Erop, Вы писали:

E>Да? А почему? Почему я не могу, например, иметь список предметов мебели в комнате, особенно если у каждого из них прописан тип, в виде аттрибута?


Ну, "если у каждого из них прописан тип, в виде аттрибута", зачем тогда иерархии? Плоская таблица (в терминологии RDBMS) решает задачу инвентаризации. А зачем еще надо "иметь список предметов мебели в комнате", кроме как для инвентаризации?
Для моделирования размещения? Тогда тем более никаких иерархий не надо. Точнее сказать, иерархия должна быть строго одноуровневая, с виртуальным методом Draw() и ему подобными.

Короче, при решении задач, все эти "иерархии", привнесенные из физического мира являются надуманными и никакого смысла не несут. Главная задача наследования — обеспечить полиморфное поведение. Это имеет смысл. Наследование как расширение функциональности — не имеет ни малейшего смысла.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[3]: Виртуальное наследование
От: Минипух Украина  
Дата: 08.09.07 20:16
Оценка: -1
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, Аноним, Вы писали:


А>>Кстати про виртуальное наследование:

А>>давно интересуют примеры его использования в реальных программах.

RO>Здесь конструктор FinalHelper должен будет быть вызван из конструктора Error (если бы наследование было невиртуальным, этот конструктор вызывался бы из конструктора Final), а Error не имеет к нему доступа, потому что он private.


Какой-то искусственный пример. Одна фича языка используется для реализации другой фичи языка.
Re: Виртуальное наследование
От: commando Россия  
Дата: 08.09.07 20:24
Оценка:
Небольшой оффтопик: посмотрел другую Вашу статью http://www.devdoc.ru/index.php/content/view/virtual_base.htm.

Вопрос: почему в иллюстрации к примеру №2 у объекта A отсутствует указатель на таблицу виртуальных функций?
Re[8]: Виртуальное наследование
От: Ruweb  
Дата: 09.09.07 09:54
Оценка: 2 (1)
Здравствуйте, McSeem2, Вы писали:

MS>Наследование как расширение функциональности — не имеет ни малейшего смысла.


Имеет смысл в задачах, где полиморфизм ну не как, не применить.
Re[8]: Виртуальное наследование
От: Erop Россия  
Дата: 09.09.07 11:21
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>Ну, "если у каждого из них прописан тип, в виде аттрибута", зачем тогда иерархии? Плоская таблица (в терминологии RDBMS) решает задачу инвентаризации. А зачем еще надо "иметь список предметов мебели в комнате", кроме как для инвентаризации?


Мало ли зачем? Скажем тебя может заинтересовать сколько мест для рассадки гостей есть в комнате, или сколько для раскладывания на ночлег. Соответсвенно нужны разные свойства. Конечно можно сделать мегаобъект "универсальное описание предмета мебели", но тогда для болшинства предметов, большинство аттрибутов будут станными...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: protected vs private
От: Erop Россия  
Дата: 09.09.07 11:24
Оценка: 1 (1)
Здравствуйте, Evgeniy13, Вы писали:

E>- Наследование вместо агрегации (не нужно лишний раз обращаться к переменной). Но в этом случае очевидно должно быть защищенное наследование.

E>- Наследование как наследования реализации (опять-таки должно быть защищенное наследование)

А почему protected, а не private?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: protected vs private
От: Ruweb  
Дата: 09.09.07 12:02
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>А почему protected, а не private?


А какая разнца для юзера protected или private члены? ни к тем, ни к тем он доступа не имеет. Уровни доступа придуманны для того, чтобы запретить юзеру юзать те или иные члены.

А юзать protected вместо private в наследовании выгодней, потому что наследник будет и иметь доступ к базовым, закрытым для юзера членам, т.е. сохраняется гипкость.

Во времени выполнения нет разницы, почемуб не юзать? или я что-то не то говорю?
Re[7]: protected vs private
От: Erop Россия  
Дата: 09.09.07 12:57
Оценка: 6 (1) +1
Здравствуйте, Ruweb, Вы писали:

R>А юзать protected вместо private в наследовании выгодней, потому что наследник будет и иметь доступ к базовым, закрытым для юзера членам, т.е. сохраняется гипкость.


А почему нет нужды защищать свои потроха от своих наследников?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: protected vs private
От: Roman Odaisky Украина  
Дата: 09.09.07 14:01
Оценка:
Здравствуйте, Ruweb, Вы писали:

R>А юзать protected вместо private в наследовании выгодней, потому что наследник будет и иметь доступ к базовым, закрытым для юзера членам, т.е. сохраняется гипкость.


Тогда вообще всегда использовать public выгодней — гибкости больше.

Я пока знаю только одно приличное применение protected, и то оно там не используется: деструкторы std::unary_function, std::iterator и прочих невиртуальных интерфейсов.
До последнего не верил в пирамиду Лебедева.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.