Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет yigal_s ([info]yigal_s)
@ 2004-05-28 16:47:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Мерзкий Страусиный Труп !
Всё же ужасно грустно, что в любимом моём С++ нет блока try-finally.

Как ни дёргайся, а пристойный exception-safe код написать никак не получается. И временами это просто уже бесит.
Image


(Добавить комментарий)


[info]ystrek@lj
2004-05-28 05:33 (ссылка)
Припоминается, что конструкции __try (...) __finally встречались ещё в примерах к Win'95. Правда, они шли как "Microsoft specific", но всё же... Что, в других компиляторах этого до сих пор нет?

(Ответить) (Ветвь дискуссии)


[info]s1m@lj
2004-05-28 06:27 (ссылка)
угу, МС-specific. ANSI С не предпологает испозование структурной обработки исключений в принципе, а для написания надежного кода структурные обработчики очень удобны.

(Ответить) (Уровень выше)


[info]yigal_s@lj
2004-05-28 13:00 (ссылка)
Да я бы с радостью... даже и Microsoft specific, черт с ним.

Вот только в одном файле невозможно написать и
C++ try-catch
и
Microsoft __try-__finally

(Ответить) (Уровень выше)


[info]s1m@lj
2004-05-28 06:30 (ссылка)
тогда ему не показалось это полезной фишкой :) зато множественное наследование поддержали -- то-то народ радуется! :)

(Ответить) (Ветвь дискуссии)


[info]yigal_s@lj
2004-05-28 13:22 (ссылка)
> тогда ему не показалось это полезной фишкой

Не знаю, не слышал.

Зато вот замечательная цитата из "The Design and Evolution of C++":

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

Вот так, "специальная техника". Зато с чудесным Абъектно-Ариентированным дизайном откатки исключений через жопу деструктор, у нас нет никакой такой "специальной и сложной техники".

Я уже не говорю про третье специальное издание "Stroustrup. The C++ Programming Language" с отдельным приложением по методам написания надежного кода, появившееся хрен его знает через сколько времени после введения самих исключений в С++. Блин, зла не хватает.

Что до мульти-наследования, то при всех его "отдельных недостатках", я так и не понял, почему его многие ругают в С++. Пользовался и не раз, правда, в не очень навороченных дизайнах. По мелочи, во всяком случае, полезная штука. Да и Borland OWL 2.0 тоже на нём подняла. Так в чем дело, может объясните?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yms@lj
2004-05-28 21:53 (ссылка)
Для того чтобы нормально использовать множественное наследование, надо, чтобы базовые классы были под это заточены изначально: напр., если у них общий родитель, то они должны ему виртуально наследовать, иначе их "имущество" удвоится:
class istream : virtual public ios
class ostream : virtual public ios

и только тогда
class iostream : public istream, public ostream

В результате вносимая путаница чаще всего превосходит по сложности решаемые проблемы. Обычно хороший дизайн позволяет обойтись без этого.
А вот множественное наследование интерфейсов — вполне нормальная вещь, тут просто накладывается функциональность, всё решаемо автоматически на уровне VMT.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yigal_s@lj
2004-05-28 23:12 (ссылка)
> чтобы базовые классы были под это заточены изначально

Да, это верно.

С другой стороны, вовсе нет железных гарантий в том, что любые базовые классы должны быть объединены через виртуальное наследование. К примеру, в Eifel-e, если не ошибаюсь, можно задавать и более сложное объединение базовых "виртуальных" классов, чем объединение всех в один инстанс. Соответственно, и вариант невиртуального наследования базового класса смысл имеет.

Поэтому представляется, что проблемы множественного наследования скорее вполне отражают "свойства реального мира", чем являются проявлением недостатков С++.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yms@lj
2004-05-29 01:11 (ссылка)
Поэтому представляется, что проблемы множественного наследования скорее вполне отражают "свойства реального мира"

Ага, и разница между простым и виртуальным наследованием тоже отражает "свойства реального мира", да?...
В любом случае, решения с дизайном, избегающим мн.н., выглядят более простыми и легче поддерживаемыми.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yigal_s@lj
2004-05-29 07:25 (ссылка)
> Ага, и разница между простым и виртуальным наследованием тоже отражает "свойства реального мира", да?...

Виртуальное наследование - лишь способ решения проблем мульти-наследования. Посему, из того, что мульти-наследование отражает объективные реалии, не следует строго, что их же должно отражать виртуальное наследование.

> В любом случае, решения с дизайном, избегающим мн.н., выглядят более простыми и легче поддерживаемыми.

Да просто проблемы на самом деле не в мульти-наследовании, а в самой концепции implementation reusing. Представьте себе, что у вас есть имплементация Base (включающая в себя данные) и имплементации A и B, реюзающие её. Использовать они её могут через наследование класса Base, через включения в себя класса Base в качестве member-a, через включение в себя указателя на класс Base.

Ну а теперь представьте себе, что имплементация C реюзает имплементации A и B - опять же, каким угодно способом. В результате, как вы не крутитесь, вы получите примерно тот же уровень головной боли, что и с мульти-наследованием. И вам опять же придется предусматривать в имплементации A и B то, что данные имплементации Base могут быть слиты.

Всё это вполне реальные проблемы, а мульти-наследование при всех его отдельных недостатках в С++ - всего лишь эти проблемы отражает, но никак уж не порождает.

(Ответить) (Уровень выше)


[info]yms@lj
2004-05-28 21:56 (ссылка)
Короче, в C++ надо запретить инцест :)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yigal_s@lj
2004-05-28 23:25 (ссылка)
В С++ надо запретить наследование.

"Наследовать" можно только интерфейс, а вот наследовать имплементации с данными, а не агрегировать их в качестве class-members, следует запретить. :-)

Viva COM !!!

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yms@lj
2004-05-29 00:51 (ссылка)
Ну уж нет, нехай себе классы наследуют, запрещать незачем.
Образцово-показательным мне сегодня представляется C#.

Viva COM !!!

Ась? А как COM реализуется, не через те же плюсовые классы с тем же самым наследованием?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yigal_s@lj
2004-05-29 01:03 (ссылка)
Беда, что "наследование" в С++ служит слишком многому сразу.

Это

и средство обеспечения полиморфизма (имплементация интерфейсов)
и средство агрегации готовых имплементаций (наследование "базовых классов")
и средство "указания стратегий" - через имплементацию pure-virtual функций функциональных (а не интерфейсных) базовых классов.

Если уж и разрешать "наследование классов", то есть, наследование имплементаций, то следует разрешать и мульти-наследование имплементаций, на мой взгляд.

> Образцово-показательным мне сегодня представляется C#.

В нём с наследованиями то же, что и в Java? Всего лишь компромиссный вариант. Не опасный, но и не богатый возможностями.

> Ась? А как COM реализуется

Через "наследование" интерфейсов, ессно. :-)

(Ответить) (Уровень выше)