На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Закрыто archimed7592 11-03-2008: Лимит страниц. Продолжаем Delphi vs C++

Страницы: (117) « Первая ... 101 102 [103] 104 105 ...  116 117  ( Перейти к последнему сообщению )  
> Delphi vs C++ , Часть 1
    Цитата Romkin @
    А зря. Потому что данный критерий является абсолютно незначимым в лобой системе оптимизации деятельости программиста. Поэтому выглядит странно...

    Ты слышал про разницу между "возможностью делать что-либо" и "обязательством делать что-либо"? :)
    Дык вот, повторю измусоленную фразу "в самой возможности ничего странного нет".

    Добавлено
    Цитата --Ins-- @
    Ну и где тут полиморфизм? Простой пример: Дан класс TStream. В нем объявлены виртуальные методы Read и Write, которые ничего не делают. У класса есть бесконечное множество потомков - TFileStream, который позволяет писать/читать из файла, TMemoryStream, который позволяет читать/писать из памяти и т.д. Виртуальные методы в них перекрыты. Есть некий клиентский код - скажем, функция, у которой один из параметров имеет тип TStream. Эта функция, допустим, выполняет запись в поток, переданный ей в качестве параметра. Так как методы Write/Read объявлены как виртуальные, то, куда будет писать функция зависит от того, какому классу действительно принадлежит переданный ей параметр. При этом код ее от этого не зависит. Согласен ли ты с тем, что это нормальный полиморфизм? А теперь объясни, зачем клиентскому коду возможность вызывать реализацию методов класса TStream, а не перекрытых в потомках методов?

    Ага, теперь понял за что ты так яро сражаешься :). В С++ эта проблема легко решается паттерном NVI(Non-Virtual Interface) и, по хорошему, в С++ (при условии нормальной архитектуры) ты редко встретишь открытый виртуальный метод. Точнее говоря, встретить можешь - в интерфейсах, но с ними немного другая ситуация :)(не охота расписывать ньансы).
    Сообщение отредактировано: b-a1 -
      --Ins--, предлагаю посмотреть на этот вопрос с другой стороны. Да, С++ позволяет явно вызвать перегруженный виртуальный метод как не виртуальный, но это возможно только в одном случае - если виртуальный метод в базовом классе помещен секцию public. Если разработчик поступил таким образом, значит он позволил обращение к этому коду извне. Логично? Логично. И, более того, если разработчик базового класса задал для этого метода какую-то реализацию, значит эта реализация имеет смысл при обращении к классу именно как к базовому. Таким образом, учитывая все приведенные обстоятельства, невиртуальный вызов перегруженного виртуального метода был разрешен проектировщиком класса (варианты "а, и так сойдет, авось никто не вызовет" - тут не рассматриваются, ибо детство). Ты тут говоришь про ООП. Давай посмотрим на этот вопрос с точки зрения ООП. Что может сделать разработчик, чтобы действительно ограничить доступность такого метода и обеспечить полиморфный вызов при любом раскладе? Ну, например, он может не делать открытые методы виртуальными (если они не абстрактные - но это отдельная песня). Тем самым он убивает сразу двух зайцев:
      1. Он запрещает (не)преднамеренные неполиморфные вызовы виртуальных методов.
      2. Он более тонко прорабатывает интерфейс класса. Ибо в данном случае интерфейс класса будет явно разделен на открытый интерфейс (для клиентов класса) и на интерфейс расширения (для производных классов), что влечет за собой только плюсы, т. к. разработчику уже не придется совмещать несовместимое. Более того, в этом случае разработчик класса имеет гораздо больше рычагов по управлению интерфейсом расширения. Он может разделить все методы на несколько групп:
      - Методы, которые обязаны быть перегружены, не имеют дефолтной реализации, и не могут быть вызваны из производных классов;
      - Методы, которые могут быть перегружены, имеют дефолтную реализацию, и не могут быть вызваны из производных классов;
      - Методы, которые обязаны быть перегружены, имеют дефолтную реализацию, и могут быть вызваны из производных классов;
      - Методы, которые могут быть перегружены, имеют дефолтную реализацию, и могут быть вызваны из производных классов;
      Первая группа методов будет сделана абстрактной и помещена в private-секцию, вторая - будет помещена в private-секцию, но при этом будет иметь дефолтную реализацию, третья - будет сделана абстрактной, размещена в protected-секции и иметь дефлтную реализацию, четвертая - отличается от третьей тем, что методы не абстрактные.
      При этом в каждом случае разработчик имеет возможность навесить дополнительные pre- post-amble-методы/действия, которые будут отвечать за обязательные действия, которые должны быть выполнены вне зависимости от того, перегружен метод в производном классе или нет. Или реализовывать более сложную логику взаимодействия открытой и защищенной частей.

      Вот, что такое проектирование на С++ с точки зрения ООП. Может Delphi предоставить такую свободу в проектировании интерфейса? Или я упрусь в стенку уже на этапе попытки перегрузки private-методов? Может мне Delphi позволить делать абстрактные методы с дефолтной реализацией (т. е. методы, которые требуют обязательной перегрузки, но при этом предлагают наследнику часть функционала)?

      Добавлено
      Собственно, пример кода:
      ExpandedWrap disabled
        class Base
        {
        public:
           void foo()
           {
              // делаем что-то важное
              Foo1Impl();
              // делаем еще что-то важное
              Foo2Impl();
              // и еще что-то делаем
              Foo3Impl();
              // и еще что-то делаем
              Foo4Impl();
              // и опять что-то делаем
           }
        protected:
           virtual void Foo4Impl() {/* какая-то реализация */;} // Этот метод может быть перегружен в потомке, но этого не требуется. Метод предоставляет потомку дефолтную реализацию
           virtual void Foo3Impl() = 0 {/* какая-то реализация */;} // Этот метод должен быть перегружен в потомке. Метод предоставляет потомку дефолтную реализацию
        private:
           virtual void Foo2Impl() {/* какая-то реализация */;} // Этот метод может быть перегружен в потомке, но этого не требуется. Метод имеет  дефолтную реализацию
           virtual void Foo1Impl() = 0; // Этот метод должен быть перегружен в потомке в любом случае.
        };


      При таком раскладе я (без злобных хаков) никак не смогу вызвать виртуальные методы невиртуально. При этом я явно (в коде) специфицировал желаемое поведение наследников.

      Добавлено
      И даже если разработчик производных классов не удосужится залезть в документацию или посмотреть (отсутствующие) комментарии на класс, базовый класс и его клиенты все равно сохранят определенные гарантии корретного функционирования класса в случае его расширения, т. к. проектировщик класса явным образом об этом позаботился и в нужных местах подложил соломку.
        Цитата Flex Ferrum @
        Ну, например, он может не делать открытые методы виртуальными (если они не абстрактные - но это отдельная песня).

        Как выразился бы mo3r - это рюшечки, причём некислые такие рюшечки. И ещё кто-то после этого имеет наглость плеваться на "лишние" try...catch :P
          Цитата wind @
          Как выразился бы mo3r - это рюшечки, причём некислые такие рюшечки. И ещё кто-то после этого имеет наглость плеваться на "лишние" try...catch

          В смысле? Где тут рюшечки то? Ты явно разделяешь контракты - на контракт с клиентом и на контракт с наследником. Или будешь пытаться в ряде случаев совместить несовместимое?
            Цитата Flex Ferrum @
            В смысле? Где тут рюшечки то?

            В смысле очень много букв (писать). И крайне неочевидно для всякого, кто не мыслит на C++ (отсюда и споры).
            В общем, даешь аннотации в C++! :P
            Сообщение отредактировано: wind -
              Цитата wind @
              В смысле очень много букв.

              Ааа... Ну-ну. :) По этому мы вводим в язык новые сущности (типа override, inherits и т. п.), дабы позволить разработчику проектировать абы как, надеясь на то, что среда в нужном месте по рукам даст? :)
                Цитата Flex Ferrum @
                По этому мы вводим в язык новые сущности (типа override, inherits и т. п.), дабы позволить разработчику проектировать абы как, надеясь на то, что среда в нужном месте по рукам даст?

                Именно, ибо удобнее, проще, понятнее и т. п. И не среда, а компилятор.
                  Научить правильно программировать и проектировать, конечно же, значительно сложнее. :)
                    Цитата Flex Ferrum @
                    Научить правильно программировать и проектировать, конечно же, значительно сложнее.

                    Боюсь, тут вы не правы. Объём рюшечек, создаваемых программистом за единицу времени или для единицы компиляции никоим образом не увязан с его способностью правильно проектировать и программировать.
                      Тогда к чему тут крики про то, что C++ опасен? При таком раскладе - конечно же опасен. Как опасна бензопила в руках обезьяны. :) Если мы ведем речь о том, чтобы новичок делал как можно меньше ошибок при написании - то к чему все разговоры о том "как правильно"? И к чему разговоры о промышленном программировании? Если под "промышленным программированием" подразумевается программирование мыкшой студентами после прочтения "Delphi/Java for dummers for 21 days", то, конечно же, С++ тут не жилец... :) Впрочем, а нужно ли оно такое промышленное программирование? И о каких вообще фундаментальных принципах ООП ведется речь? :)
                        Цитата Flex Ferrum @
                        При таком раскладе - конечно же опасен. Как опасна бензопила в руках обезьяны.

                        :yes:

                        Цитата Flex Ferrum @
                        И к чему разговоры о промышленном программировании?

                        Промышленное программирование - это стада обезьян, причём обезьян без шансов на эволюционирование.
                          Цитата wind @
                          Боюсь, тут вы не правы. Объём рюшечек, создаваемых программистом за единицу времени или для единицы компиляции никоим образом не увязан с его способностью правильно проектировать и программировать.

                          Да ну что ты? Пока на все свои возражения в стиле: "профессионал так будет поступать только в очень малом количестве случаев, а новичок и без этого дров наломает" я получал в ответ в стиле: "а все равно, нож острый, значит можно порезаться". Таким образом, косвенно, но увязан. Тот, кто знает - как проектировать, вполне может обойтись имеющимися средствами, причем весьма виртуозно. А вот тот, кто не знает, вынужден опираться исключительно на то, дадут ему по рукам или нет. Если не дадут - то и хорошо. А если дадут, то будет думать, как делать иначе. Но не раньше. :)

                          Добавлено
                          Цитата wind @
                          Промышленное программирование - это стада обезьян, причём обезьян без шансов на эволюционирование.

                          Ааааа... Ну да, я забыл - coding for money. Чем больше строчек написал, тем больше денюжек получил. В этом случае, конечно же, самым идеальным средством разработки были бы детские кубики... :) Только вот как называются те, кто делают эти кубики? Или их авторы - тоже те самые стада обезьян? Только одни - это бабуины, а другие - шимпанзе? :)
                            Цитата Flex Ferrum @
                            Таким образом, косвенно, но увязан.

                            Никак не увязан. Если в двух языках для достижения эквивалентных результатов требуется приложить различное количество усилий (а залогом успешного применения будет различное количество знаний о языке), то эта разница никак не характеризует программистов, пишущих на этих языках, с точки зрения их умений создавать правильную архитектуру.
                              Цитата wind @
                              Никак не увязан. Если в двух языках для достижения эквивалентных результатов требуется приложить различное количество усилий (а залогом успешного применения будет различное количество знаний о языке), то эта разница никак не характеризует программистов, пишущих на этих языках с точки зрения их умений создавать правильную архитектуру.

                              Ну тогда продемонстрируй - как именно java или delphi может мне помочь в четкой спецификации упомянутых выше контрактов? А мы посчитаем количество строчек. :)

                              Добавлено
                              Про количество усилий я не говорю. Ибо все, что я описал, укладывается в объем знаний, полученных в процессе одного из "21 одного уроков". :) Вопрос - в комбинации полученных знаний. :)
                                Цитата Flex Ferrum @
                                Ну тогда продемонстрируй - как именно java или delphi может мне помочь в четкой спецификации упомянутых выше контрактов?

                                На java - никак, на delphi - не знаю. Я вообще-то говорю о рюшечках, а не о возможностях этих двух языков. Например, о NVI.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (117) « Первая ... 101 102 [103] 104 105 ...  116 117
                                Закрыто archimed7592 11-03-2008: Лимит страниц. Продолжаем Delphi vs C++



                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1411 ]   [ 15 queries used ]   [ Generated: 23.07.25, 17:00 GMT ]