А>>>На практике она означает, что Вы получили еще одну возможность достичь неопределенного поведения без диагностики со стороны компилятора.
ЗХ>>это почему же?
А>Потому, что при открытом наследовании Вы получаете возможность удалять производный объект через указатель на базовый.
А если я так удалять не буду? И запомню, что делаю нехорошо.
Все работать будет?
А если буду, но производный класс не содержит дополнительных переменных?
T>>И чем это грозит?
А>Неопределенным поведением при удалении через указатель на базовый класс.
А в остальном все будет работать корректно?
---
С уважением,
Лазарев Андрей
Re[9]: vector<int> = int
От:
Аноним
Дата:
24.10.03 10:49
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:
А>>>>На практике она означает, что Вы получили еще одну возможность достичь неопределенного поведения без диагностики со стороны компилятора.
ЗХ>>>это почему же?
А>>Потому, что при открытом наследовании Вы получаете возможность удалять производный объект через указатель на базовый.
ЗХ>ну и что?
Неопределенное поведение, как и было сказано.
Re[10]: vector<int> = int
От:
Аноним
Дата:
24.10.03 10:50
Оценка:
Здравствуйте, Tan4ik, Вы писали:
T>>>И чем это грозит?
А>>Неопределенным поведением при удалении через указатель на базовый класс.
T>А в остальном все будет работать корректно?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Зверёк Харьковский, Вы писали:
А>>>>>На практике она означает, что Вы получили еще одну возможность достичь неопределенного поведения без диагностики со стороны компилятора.
ЗХ>>>>это почему же?
А>>>Потому, что при открытом наследовании Вы получаете возможность удалять производный объект через указатель на базовый.
ЗХ>>ну и что?
А>Неопределенное поведение, как и было сказано.
( шизофрения, как и было сказано (c) Булгаков? )
ну при отсутствии виртуального деструктора — таки да. но с эти я уже согласился.
Здравствуйте, Tan4ik, Вы писали:
А>>>>На практике она означает, что Вы получили еще одну возможность достичь неопределенного поведения без диагностики со стороны компилятора.
ЗХ>>>это почему же?
А>>Потому, что при открытом наследовании Вы получаете возможность удалять производный объект через указатель на базовый.
T>А если я так удалять не буду? И запомню, что делаю нехорошо.
запомню — это не есть хорошо...
потом придет кто-нибудь твою прогу поддерживать — и гаплык.
насчет запомню — это целая философия.
понимаешь, многие вещи вместо того чтобы вставлять ограничения в код. можно написать в доках — не делайте того, не делайте этого.
но спасибо тебе никто не скажет
такие, блин, пирожки с котятами — их ешь, а они мяукают.
T>А если буду, но производный класс не содержит дополнительных переменных?
хрен его знает
T>P.S. Это уже чисто познавательный интерес.
FAQ — це мiй ай-кью!
Re[11]: vector<int> = int
От:
Аноним
Дата:
24.10.03 12:06
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:
А>>>>Потому, что при открытом наследовании Вы получаете возможность удалять производный объект через указатель на базовый.
ЗХ>>>ну и что?
А>>Неопределенное поведение, как и было сказано.
ЗХ>( шизофрения, как и было сказано (c) Булгаков? )
ЗХ>ну при отсутствии виртуального деструктора — таки да.
И мне жаль! (c)
Re[10]: vector<int> = int
От:
Аноним
Дата:
24.10.03 12:08
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:
T>>А если буду, но производный класс не содержит дополнительных переменных?
ЗХ>хрен его знает
Независимо. Стандарту здесь важно только несовпадение динамического и статического типов при отсутствии виртуального деструктора.
Здравствуйте, Аноним, Вы писали:
А>>>На практике она означает, что Вы получили еще одну возможность достичь неопределенного поведения без диагностики со стороны компилятора.
ЗХ>>это почему же?
А>Потому, что при открытом наследовании Вы получаете возможность удалять производный объект через указатель на базовый.
Используемая Вами логика примерно аналогична совету избегать использования в С++ коде операции деления, т.к. она может привести к делению на нуль.
Это не повод избегать наследования в данном конкретном случае. Это повод не удалять производный объект через указатель на базовый, но не более.
Best regards,
Андрей Тарасевич
Наследование от классов без виртуального деструктора?
Здравствуйте, Bell, Вы писали:
B>В данном да. Но ИМХО всегда следует придеживаться определенных правил. При программировании на С++ самодисциплина играет далеко не самую последнюю роль.
Правило "Не делать наследования от классов без виртуального деструктора" является одним из тех ложных правил, которые были популярны среди С++ программистов среднего примерно пару лет назад. Это правило успешно умерло, как и другие ложные правила типа "Каждая функция должна иметь только одну точку выхода" и т.п. Точнее, это правило не сколько умерло, сколько наконец отодвинулось на свое правильное место — в узкую область классического ООП программирования на С++ с применением динамического полиморфизма.
По моему мнению, причина ошибочной популярности этого правила, как глобального С++ правила, заключалась в том, что не очень хорошо подготовленным читателям стало доступно большое количество книг по классическому ООП на С++ (хороших книг, надо сказать), которые они тем не менее ошибочно принимали за универсальные книги по С++.
Мне странно видеть, что это ложное правило еще живет в этой конференции. Наследовать от стандартных контейнеров можно и нужно, в тех ситуациях, когда это оправданно. Наличие или отсутсвие виртуального деструтора при этом никакой роли не играет. Виртуальный деструктор — атрибут полиморфного класса. Здесь же никто не пытается создать полиморфный класс.
ЗХ>>фраза "Контейнеры STL не предназначены для наследования" означает. что у них нет виртуальных методов, которые можно было бы переопределить в наследнике. B>В том числе у них нет виртуального деструктора.
Это соврешнно не важно. Это означает, только то, что такие объекты не являются полиморфно-удаляемыми и не более. Тем не менее это не повод отказываться от наследования, если это действительно необходимо. В generic programming наследование применяется для достижения подобных целей повсеместно. Задаваться при этом вопросом о каком-то виртуальном деструкторе, мягко говоря, неуместно.
ЗХ>>...а для расширения функциональности паблик-наследование самое оно. B>Спорное утверждение, ну да ладно...
Это утверждение перестало быть спорным довольно давно. Строго говоря, такое применение публичного наследования упоминает еще Страуструп в D&E. Александреску в "Modern C++ Design" использует публичное наследование для подобных целей приктически повсеместно.
ЗХ>>...либо делать обертки ко всем его операциям. B>Да, интерфейс придется повторить. Это так ужасно?
Это соврешенно неприемлемо. Да и зачем, если есть публичное наследование?
Best regards,
Андрей Тарасевич
Re[9]: vector<int> = int
От:
Аноним
Дата:
25.10.03 08:33
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:
А>>>>На практике она означает, что Вы получили еще одну возможность достичь неопределенного поведения без диагностики со стороны компилятора.
АТ>Используемая Вами логика примерно аналогична совету избегать использования в С++ коде операции деления, т.к. она может привести к делению на нуль.
Вы напрасно усмотрели в моем утверждении какую-то оценочность. Ее там нет.
Я советую лишь, используя операцию деления, знать, что деление на ноль приведет к неопределенному поведению.
Здравствуйте, Андрей, Вы писали:
ЗХ>>> фраза "Контейнеры STL не предназначены для наследования" означает. что у них нет ЗХ>>> виртуальных методов, которые можно было бы переопределить в наследнике.
B>> В том числе у них нет виртуального деструктора.
AT> соврешнно не важно. Это означает, только то, что такие объекты не являются AT> полиморфно-удаляемыми и не более.
Невиртуальность членов std::vector, помимо того, что, в частности, объекты унаследованного
класса (VectorEx) не являются полиморфно-удаляемыми, в общем, приводит еще и к тому, что
инварианты VectorEx могут нарушаться, если где-нибудь есть модификация объектов VectorEx
через ссылки/указатели на std::vector.
B>> Да, интерфейс придется повторить. Это так ужасно?
АТ> Это соврешенно неприемлемо. Да и зачем, если есть публичное наследование?
Еще лучшим вариантом, вероятно, было бы наличие какого-нибудь встроенного механизма,
позволяющего получить в VectorEx тот же интерфейс, что и в std::vector, но не позволять,
по крайней мере, неявное приведение VectorEx* -> std::vector*.
P.S. естественно, если инварианты VectorEx тождественны инвариантам std::vector,
упомянутых проблемы не имеют никакого значения.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен