cd_riper ([info]cd_riper) wrote,

Горе от ума

Прочитал на хабре веселую статью под названием "Как безопасно разрушить объект. И другие мысли"
http://habrahabr.ru/blogs/cpp/110850/

Собственно "безопасно разрушить объект" это про классические, тысячу раз пережеванные, грабли, когда тип имеет не виртуальный деструктор и при этом экземпляры этого типа пытаются удалять через указатель на базовый класс (многие компиляторы умеет отслеживать подобную проблему и выдают соответствующие предупреждения).

Что касается "других мыслей", то это было бы смешно, если бы не было так грустно.
Сначала я подумал, что все эти бредни написал какой-то студент-теоретик, который начитался много умных книг, но его практика дальше пары хеловордов не заходила. Заглянул человеку в профиль -- да нет, на студента он мало похож. Человек вроде опытный и чем-то там даже руководит. Правда кодит в последнее время все больше на питоне... А по плюсам у человека диагноз очевидный -- нет реальной практики на фоне прочитанных хороших и правильных книг. Абсолютно типичный персонаж, я видел таких людей на технических руководящих позициях. Они блистают дословными цитатами из Страуструпа и ссылками на конкретные подразделы плюсового стандарта (как будто им завтра нужно будет самим писать компилятор), но на этом все их знания и заканчиваются. Практики они просто никакие, но зачем это руководителю, который может поставить на место абсолютно любого своего подчиненного никому ненужными энциклопедическими подробностями, ведь верно?

Но вернемся к нашим баранам.
Как вам, к примеру, такой мощный вывод нашего гения?
"Полиморфное удаление — подозрительная штука"

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

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

Нет, я не против NVI. Эту политику я сам всеми силами одобряю, дык не стоит путать хрен с пальцем и доводить любое правильно до маразма, возводя в абсолют! Автору правильно написали: "только не надо забывать что деструктор — это чисто техническая вещь, к обязанностям интерфейса класса он как правило не имеет ни малейшего отношения".

Вместо того, чтобы рассуждать на тему "должен ли быть деструктор public или protected" я бы на месте автора лучше бы написал о том, что наследование в хороших программах используется довольно редко, т.к. композиция значительно более полезный подход (при этом я, разумеется, не отрицаю повсеместной "реализации интерфейсов", которая в плюсах технически сводится к тому же наследованию).
Или может лучше автор написал бы о том, что хороший деструктор, это деструктор, которого вообще нет. А за деструктор, в котором пишется "delete" нужно обрывать человеку руки-ноги...

Рекомендация "избегать виртуальных методов" ничего кроме желания покрутить пальцем у виска не вызывает. С одной стороны, вряд ли мало-мальски опытный программист будет этой виртуальность злоупотреблять. А с другой -- в плюсах виртуальные методы это фактически единственный способ определять разное поведение в runtime (switch по какому-то полю мы всерьез не рассматриваем, ведь верно?). Как вообще можно "пересмотреть" дизайн практически любой реальной программы, чтобы в ней был минимум такого "подозрительного" поведения??

Вот вам на 100% типичный, встречающийся во множестве реальных программ, пример с использованием виртуального удаления, взятый из подсистемы, над которой я в данным момент работаю.
Есть класс "голосовой канал". Под капотом у него есть "кодек", который определяется в runtime во время установления связи с удаленной стороной. Голосовых кодеков в природе существует воз и маленькая тележка. Все очевидно и просто -- есть фабрика кодеков, которая по ID создает соответствующий объект и возвращает его в виде IVoiceCodec. Этот интерфейс голосовой канал сохраняет себе в scoped_ptr и дальше с помощью него реализует свою функциональность. В деструкторе, понятное дело, происходит то самое виртуальное удаление. Чем это удаление "подозрительно"? Чем плох такое дизайн?

На эти вопросы мы вряд ли получим вразумительные ответы от автора, любящего строить свои аналогии на теме МКАДа и асфальтоукладки.

зы. Автора конкретно бомбят в комменатах:

"Хорошая статья — удачное жонглирование псевдологикой. Элементарные и корректные примеры… не относящиеся к теме. Все остальное — метафоры, «не вызывает ни у кого сомнений», «не есть хорошо и может выйти вам боком» и прочие откровения британских ученых.
Единственный корректный аргумент во всей статье — не может использоваться в объединениях. Ну ради объединений не грех отказаться от ООП."


или

"у меня от статьи когнитивный диссонанс какой-то, простите.
А может это вброс такой?"
Tags: c++, programming

  • Post a new comment

    Error

    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    Your reply will be screened

    Your IP address will be recorded 

  • 81 comments

[info]sov_hoz

December 29 2010, 10:33:31 UTC 1 year ago

Жуть какая-то. В девелопменте с таким встретиться - не дай бог, если погонят из девелопмента он же преподавать устроится - это аццкий п-ц.
Забавно, что он ответил на ваш пост "Авторитетов автор, очевидно, не признаёт. Книжки для него не аргумент". Сам в исходной статье не дав ни одной цитаты/ссылки. Неадекват полный.

[info]cd_riper

December 29 2010, 10:37:46 UTC 1 year ago

> не дай бог, если погонят из девелопмента он же преподавать устроится

скажем так, это будет еще не самый плохой преподаватель, на фоне тех людей, которые этим занимаются сегодня :)

[info]mr_aleph

December 29 2010, 13:00:56 UTC 1 year ago Edited:  December 29 2010, 13:01:07 UTC

хабрахабр вообще подозрительная штука.

я там стараюсь статьи про серьезные вещи не читать, боюсь моя шапочка из фольги прогорит...

[info]flashnik86

December 29 2010, 14:07:11 UTC 1 year ago

> А за деструктор, в котором пишется "delete" нужно обрывать человеку руки-ноги...
Простите, может, я чего не понимаю, но в чем тут проблема?

[info]cd_riper

December 29 2010, 14:12:39 UTC 1 year ago

http://cd-riper.livejournal.com/101239.html

нужно всегда использовать смартпоинтеры. это защищает тебя от проблем.

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

[info]flashnik86

December 29 2010, 14:35:35 UTC 1 year ago

>нужно всегда использовать смартпоинтеры. это защищает тебя от проблем.
Категоричность бы поубавить :)
Использование умных указателей, RAII - клевые парадигмы, но не единственные. Иногда ими приходится пожертвовать. Согласен?

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]mifki

1 year ago

Deleted comment

[info]cd_riper

1 year ago

Deleted comment

[info]cd_riper

1 year ago

Deleted comment

[info]cd_riper

1 year ago

[info]cd_riper

December 29 2010, 14:13:35 UTC 1 year ago

да, разумеется, в реализации shared_ptr delete в деструкторе уместен :)

[info]cd_riper

December 29 2010, 14:17:05 UTC 1 year ago

Copy Source | Copy HTML
class X
{
    A *m_a;
    B *m_b;
    C *m_c;
 
public:
 
    X()
    {
       m_a = new A(); // can throw!    
       m_b = new B(); // can throw!    
       m_c = new C(); // can throw!           
    }
 
    ~X()
    {
       delete m_a;
       delete m_b;
       delete m_c;
    }
 
};

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

Anonymous

1 year ago

[info]cd_riper

1 year ago

Anonymous

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]den7b

1 year ago

[info]cd_riper

1 year ago

[info]den7b

1 year ago

[info]cd_riper

1 year ago

[info]den7b

1 year ago

[info]cd_riper

1 year ago

[info]den7b

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]the_chiffa

December 29 2010, 14:26:38 UTC 1 year ago

Исходный псто - плохой пересказ статьи из книги Саттера "Новые сложные задачи на C++".

[info]oshpaz

December 29 2010, 17:07:01 UTC 1 year ago

Я не особый читатель хабра, но большинство того, что я там читал оказывается плохими переводами заграничных источников. Что печально.

[info]kisa_i_osya

January 3 2011, 15:42:18 UTC 1 year ago

Хм. А кстати похоже. И получается, что товарищи довольно часто деликатно тырят контент, что ли таким забавным образом.

[info]cd_riper

1 year ago

Anonymous

December 29 2010, 17:50:58 UTC 1 year ago

Судя по
> Вот вам на 100% типичный, встречающийся во множестве реальных программ, пример
ты пишешь "бизнес-логику" - код, который намертво привязан к предметной области и не переиспользуется. Как правило, такой код - это комбинация небольшого количества "шаблонов", таких как "фабрика объектов", "умный указатель" и т.д. Более сложные конструкции не нужны и даже опасны - можно ввести в заблуждение коллег.

Похоже, автор статьи на хабре занимался принципиально другими вещами. Например, написанием переиспользуемых библиотек. Естественно, у него другой опыт использования С++ и другой взгляд на вещи. И в рамках своих задач он прав, а ты - нет.

Посмотри код известных библиотек для C++. Например, STLport, boost, Qt. Там идиома "виртуальный деструктор + умный указатель" используется достаточно редко, если вообще используется. И это правильно - представь, что строки и контейнеры STL нужно было бы использовать через "умные указатели". Стал бы ты пользоваться такой библиотекой?

[info]cd_riper

December 29 2010, 18:41:57 UTC 1 year ago

> Более сложные конструкции не нужны и даже опасны

ну расскажи тогда, где в STL или Qt используются более сложные конструкции. я весь во внимании.

кроме того, библиотека это вещь в себе. без приложения, которое ее использует это вообще ни о чем.

> представь, что строки и контейнеры STL нужно было бы использовать через "умные указатели"

о чем вообще эти изъяснения?
строка или комплексное число это конкретные типы (в терминологии Страуструпа) со всеми вытекающими из этого последствиями.
на одних конкретных типах ничего, кроме обсчета какой-то математики не построишь.

Anonymous

1 year ago

[info]cd_riper

1 year ago

Anonymous

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

December 30 2010, 11:18:31 UTC 1 year ago

кстати, в Qt 300 заголовочных файлов из 1100 содержат слово virtual.
в 172 заголовочных файлах обнаружены виртуальные деструкторы.
ы?

Anonymous

1 year ago

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

Anonymous

1 year ago

[info]cd_riper

1 year ago

Anonymous

December 30 2010, 13:09:34 UTC 1 year ago

Кстати, а неплохой вопрос на собеседование - "почему в STL идиома "виртуальный деструктор + умный указатель" используется достаточно редко, если вообще используется?". На понимание шаблонов и STL.

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]ivansorokin

December 31 2010, 02:01:00 UTC 1 year ago

Прочитал. Чувак ёбнутый. Не обращай внимание.

[info]kisa_i_osya

January 3 2011, 15:37:31 UTC 1 year ago

Ох товарищ, ведь чтение Хара -- первый шаг на пути к деградации... ;-)

Читаешь, хихикаешь, думаешь какие идиоты... Но исподволь привыкаешь к тому, что _так_можно_. и перестаешь понимать "а отчего так нельзя".

(Наблюдалось три клинических случая ;-)

[info]cd_riper

January 3 2011, 15:53:47 UTC 1 year ago

у меня хватает мозгов, чтобы понимать что хорошо, а что плохо и не попадать под дурное влияние :)

[info]cd_riper

1 year ago

[info]cd_riper

1 year ago

[info]smoker_only

January 19 2011, 11:24:52 UTC 1 year ago

+1!

[info]vaddimka

January 23 2011, 09:45:29 UTC 1 year ago

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

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

[info]cd_riper

January 23 2011, 09:53:21 UTC 1 year ago

шаблоны вообще-то очень слабо пересекаются с виртуальными функциями, ибо compile-time и runtime полиморфизм это принципиально разные вещи.

[info]Anatoly Borodin [myopenid.com]

January 30 2011, 13:15:18 UTC 1 year ago

> Или может лучше автор написал бы о том, что хороший деструктор, это деструктор, которого вообще нет.

Так-то оно так, но если

struct A
{
MyObj1 x;
};

struct B : public A
{
MyObj2 y;
};

то при A* ptr = new B; delete ptr; // pardon

~MyObj2() не вызовется. Так что аккуратность нужна всегда.

[info]cd_riper

January 30 2011, 13:17:30 UTC 1 year ago

а к чему это все вообще?

[info]cd_riper

1 year ago

[info]bybor [ya.ru]

February 17 2011, 08:41:50 UTC 1 year ago

А что бы такое почитать по современному C++

А нет случайно списка книг, которые хорошо расскажут про современный С++? Или надо читать Александреску/Саттера/исходники Boost/текст стандарта/много думать?

Со времен института не писал на плюсах, и как-то всё совсем по-другому. Я так понимаю, что книги Мейерса это тоже слишком low-level?

Спасибо.

[info]cd_riper

February 17 2011, 09:14:05 UTC 1 year ago

Re: А что бы такое почитать по современному C++

> Или надо читать Александреску/Саттера/исходники Boost/текст стандарта/много думать?

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

конкретно по метапрограммированию
http://www.boost.org/doc/libs/1_45_0/libs/mpl/doc/tutorial/resources.html

[info]cd_riper

1 year ago

Create an Account
Forgot your login or password?
Facebook Twitter More login options
English • Español • Deutsch • Русский…