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

Страницы: (117) « Первая ... 102 103 [104] 105 106 ...  116 117  ( Перейти к последнему сообщению )  
> Delphi vs C++ , Часть 1
    Цитата Flex Ferrum @
    - Методы, которые обязаны быть перегружены, не имеют дефолтной реализации, и не могут быть вызваны из производных классов;

    Цитата Flex Ferrum @
    Первая группа методов будет сделана абстрактной и помещена в private-секцию

    наследник имеет доступ к private-секции предка? :blink:
    а абстрактный метод в private-секции - это вообще ересь (в Delphi)
      А к чему тут вообще крики о каких-то канонах ООП или достоинствах/недостатках Дельфи/С++, когда промышленость - это всего лишь стадо обезьян?

      Цитата Shaggy @
      наследник имеет доступ к private-секции предка? :blink:

      Виртуальность определяется лишь сигнатурой. Расположение относительно спецификатора доступа(public/protected/private) не имеет значения при вызове реализации. Спецификатор доступа имеет значение лишь при разрешении имён(какую ф-цию вызываем), а дальнейший механизм "поиска" конкретной реализации(по VMT) не в курсе о том, в какой секции эта реализация расположена и доступна ли эта секция из точки вызова.
      В Дельфи всё устроено точно также, только, возможно, компилятор запрещает перекрывать закрытые виртуальные метода.
        Цитата b-a1 @
        А к чему тут вообще крики о каких-то канонах ООП или достоинствах/недостатках Дельфи/С++, когда промышленость - это всего лишь стадо обезьян?

        К тому, что этих обезьян нужно как-то приспособить для создания более-менее вменяемого кода. Широкие возможности для совершения ошибок в руках обезьян подобные усилия сводят на нет.
          b-a1
          Цитата
          Вспоминаем основы разделения доступа в Delphi .
          Public доступен всем кому угодно.
          Protected доступен в любом модуле, в котором ты наследуешься от данного класса.
          Private доступен в модуле, в котором присутствует объявление данного класса.
          В итоге, делая forward declaration нужного класса(да, с синтаксисом я немного ошибся), мы получаем доступ в private/protected нужного класса на весь модуль целиком. Разве нет?


          Ты кое что не учел :) private позволяет получить доступ к члену класса в пределах именно модуля, а не класса, это документированное поведение. Тут судя по всему наложилась идеология языка Pascal. Но эта проблема в Delphi уже давным-давно решена, существуют секции strict private и strict protected, которые ограничивают видимость именно внутри класса, а не внутри модуля, private/protected оставлены для совместимости со старым кодом.

          Ты, как ветеран данного холивара (должен хорошо разбираться в теме), лучше расскажи мне другое :) А именно, где в Delphi встроены понятия user-mode, kernel-mode, API :) А то ведь слово - оно не воробей :) А заодно, когда будешь говорить о платформозависимости языка, вспомни о Kilyx и Delphi.NET

          Добавлено
          Цитата
          Дык вот, повторю измусоленную фразу "в самой возможности ничего странного нет".


          Сама возможность нарушить принцип инкапсуляции, скажем, сводит этот принцип на нет :)

          Добавлено
          Flex Ferrum

          Ваши третий и четвертый пункт, о которых вы говорите, и выдаете их за "сверхгибкий" механизм, на самом деле является именно рюшечкой. Так как не должно быть такого в грамотно спроектированной системе. Нельзя заставить собаку реветь, но если возникает такая необходимость - то стоит пересмотреть архитектуру. Хотя никто в C++ этим, разумеется, заниматься не будет, бо язык позволяет это обойти. Вы посмотрите на это не со стороны возможностей C++, а со стороны ограничений ООП :) Если тебе нужен статический вызов - делай статический метод. Если тебе нужен полиморфный вызов - делай метод виртуальным. Но статический вызов виртуального метода - нонсенс.
            Цитата --Ins-- @
            Ты кое что не учел private позволяет получить доступ к члену класса в пределах именно модуля, а не класса, это документированное поведение. Тут судя по всему наложилась идеология языка Pascal.

            Угу. И решена эта проблема не очень давно. И, к сожалению, такой доступ и до сих пор используется в VCL :(
            На самом деле, это было сделано изначально для совместимости с TP7.
            Но из другого модуля получить доступ к private, насколько я знаю, нельзя иначе как грубым хаком.
              Цитата --Ins-- @
              Сама возможность нарушить принцип инкапсуляции, скажем, сводит этот принцип на нет :)

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

              Цитата Flex Ferrum @
              С++ - это мультипарадигменный язык.

              То есть C++ не является объектно-ориентированным языком; он предоставляет возможность писать объектно-ориентированный код, а это две большие разницы. И для человека, знающего C++, нет ничего противоестественного в существовании некоторых значимых нюансов, неразличимых для прочих. Просто это другой язык, язык, который нужно хорошо знать, чтобы писать что-то вменяемое :)
                Цитата
                Угу. И решена эта проблема не очень давно.


                5-6 лет как, если не ошибаюсь. Вроде с Delphi 8.

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


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

                wind

                Возможно. Вот только взгляд на ООП в C++ по меньшей мере странный, как мне кажется. Правильно Romkin однажды заметил, что перейти с C++ на какой-либо другой язык будет сложно, не поймешь идеологию, в которой слишком много ограничений :)
                  Цитата --Ins-- @
                  Ваши третий и четвертый пункт, о которых вы говорите, и выдаете их за "сверхгибкий" механизм, на самом деле является именно рюшечкой. Так как не должно быть такого в грамотно спроектированной системе. Нельзя заставить собаку реветь, но если возникает такая необходимость - то стоит пересмотреть архитектуру. Хотя никто в C++ этим, разумеется, заниматься не будет, бо язык позволяет это обойти. Вы посмотрите на это не со стороны возможностей C++, а со стороны ограничений ООП :) Если тебе нужен статический вызов - делай статический метод. Если тебе нужен полиморфный вызов - делай метод виртуальным. Но статический вызов виртуального метода - нонсенс.

                  Видимо, ты не совсем понял - о чем идет речь. Если предоставление дефолтной реализации некоего виртуального метода нарушает какие-то фундаментальные принципы ООП - то какие? Проектировщик класса свободен в своем выборе - как и каким образом ему проектировать интерфейс и контракты. Чем это нарушает принципы ООП?
                    Цитата
                    Если предоставление дефолтной реализации некоего виртуального метода нарушает какие-то фундаментальные принципы ООП - то какие?


                    Те, что виртуальные методы по определению являются методами позднего связывания. Если нужно использовать базовую реализацию в классе-потомке, заведи у базового класса статический метод. Хотя я, если честно, не могу представить ситуацию, где такое (именно вызов виртуального метода как статического) может потребоваться и быть оправдано.

                    Цитата
                    Проектировщик класса свободен в своем выборе


                    Вот в этом и вся соль. Вы называете это свободой, а я - вседозволенностью. Вы смотрите на нее с положительной стороны, а я - с отрицательной.

                    Добавлено
                    Цитата
                    Хотя я, если честно, не могу представить ситуацию, где такое (именно вызов виртуального метода как статического) может потребоваться и быть оправдано.


                    Если не возражаете - еще один пример из своей недавней практики. У меня был базовый класс TPalette - некая палитра. У него была куча потомков - TRGBPalette, THLSPalette, TLABPalette. У базового класса был объявлен виртуальный метод Default, который сбрасывал палитру в состояние по умолчанию. Его реализация:
                    TPalette - устанавливает равномерную ч/б палитру
                    TRGBPalette - устанавливает равномерную ч/б палитру
                    THLSPalette - устанавливает равномерную радужную палитру
                    TLABPalette - градиентный переход от оранжевого через белый к голубому.
                    В потомках класса TPalette часто приходилось также устанавливать черно-белую палитру. В C++ вы бы наверняка для этого вызывали виртуальный Default как статический для класса TPalette. Так? Недостаток такого подхода в том, что клиентский код должен знать об аспектах реализации базового класса. Это не есть гуд, так как в идеале базовый класс должен только предоставлять интерфейс клиенту, его реализация клиента не волнует. Я поступил иначе - завел у TPalette публичный метод GrayScale, а реализация TPalette.Default просто его вызывала. В результате я получил тот же самый эффект, только клиенту кроме интерфейса о базовом классе ничего знать не нужно. И нет никаких грязных вызовов виртуальных методов как статических.
                      Цитата --Ins-- @
                      Те, что виртуальные методы по определению являются методами позднего связывания. Если нужно использовать базовую реализацию в классе-потомке, заведи у базового класса статический метод. Хотя я, если честно, не могу представить ситуацию, где такое (именно вызов виртуального метода как статического) может потребоваться и быть оправдано.

                      Ты до сих пор не понимаешь о чем я говорю. Простой пример:

                      ExpandedWrap disabled
                        class Base
                        {
                        public:
                           void foo() {FooImpl();}
                           void bar() {BarImpl();}
                        protected:
                           void FooImpl() {std::cout << "Base::FooImpl" << std::endl;}
                           void BarImpl() {std::cout << "Base::BarImpl" << std::endl;}
                        };
                         
                        class Derived : publiс Base
                        {
                        protected:
                           void FooImpl() {Base::FooImpl(); std::cout << "Derived::FooImpl" << std::endl;}
                        };
                         
                        //...
                        Base b1;
                        Derived d1;
                         
                        Base* b2 = &d1;
                         
                        b2->foo(); // На экран выведется Base::FooImpl Derived::FooImpl
                        b2->bar(); // На экран выведется Base::BarImpl
                        //...


                      Чем этот код нарушает принципы ООП?

                      Добавлено
                      Или для тебя не понятна разница между контрактом с клиентом и контрактом с наследником? И чем отличаются спецификаторы public и protected?
                        Цитата
                        Чем этот код нарушает принципы ООП?


                        Именно этот - ничем. Здесь все нормально, через ссылку b2 методы вызываются именно как виртуальные. А вызов унаследованной реализации в перекрытой - это нормально. Об этом уже речь была несколько страниц назад.

                        Добавлено
                        Цитата
                        Или для тебя не понятна разница между контрактом с клиентом и контрактом с наследником? И чем отличаются спецификаторы public и protected?


                        Понятно, я понял теперь о чем вы. В приведенном коде - все в порядке.
                          Цитата --Ins-- @
                          Понятно, я понял теперь о чем вы. В приведенном коде - все в порядке.

                          Так вот я и спрашиваю - могу ли я подобные фишки проворачивать в Delphi? :)
                            Цитата
                            могу ли я подобные фишки проворачивать в Delphi?


                            Да. Директива inherited используется в реализации классов-потомков, позволяя вызывать из них реализацию предка, дабы не дублировать код:

                            ExpandedWrap disabled
                              TDerived = class(TBase);
                              public
                                procedure FooImpl; override;
                              end;
                              ...
                              procedure TDerived.FooImpl;
                              begin
                                inherited FooImpl;
                                Writeln('Derived.FooImpl');
                              end;


                            В клиентском же коде возможность использования директивы inherited языком не предусмотрена.
                              А если я хочу с одной стороны - потребовать обязательной перегрузки метода в потомке, с другой - предложить этому потому дефолтную реализацию этого метода. Что мне делать?
                                Цитата Flex Ferrum @
                                Так вот я и спрашиваю - могу ли я подобные фишки проворачивать в Delphi?

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



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