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

Страницы: (117) « Первая ... 95 96 [97] 98 99 ...  116 117  ( Перейти к последнему сообщению )  
> Delphi vs C++ , Часть 1
    Цитата
    Убери директиву overload у предка. Потому что обычно ее там нет.


    Понятно, не додумался. Вообще, это как-то неправильно по-моему. Зачем выдавать варнинг, что скрывается предыдущее объявление, если на самом деле оно не скрывается?
      Цитата --Ins-- @
      Вообще, это как-то неправильно по-моему. Зачем выдавать варнинг, что скрывается предыдущее объявление, если на самом деле оно не скрывается?

      Почему не скрывается? Скрывается. Это просто вежливость: ты объясняешь компилятору, что это ты не ошибся в объявлении параметров и имени метода, а именно так ты и хочешь. Одной директивы overload недостаточно для этого, мало ли, может, ты еще один метод в потомке напишешь :)
        Я понимаю, что reintroduce нужен для того, чтобы заткнуть рот Delphi, мол я знаю, что делаю. Но по-моему Delphi иногда врет, говоря, что декларация метода скрывается. Что-то я вообще запутался :) Смотри, в этом случае:
        ExpandedWrap disabled
            T1 = class(TObject)
              procedure Test(I: Integer); virtual;
            end;
            T2 = class(T1)
              procedure Test(S: string); overload; virtual;
              procedure Test(E: TObject); overload; virtual;
            end;


        Ничего не скрывается. А в этом:
        ExpandedWrap disabled
            T1 = class(TObject)
              procedure Test(I: Integer); virtual;
            end;
            T2 = class(T1)
              procedure Test(S: string); overload; virtual;
              procedure Test(E: Extended); overload; virtual;
            end;


        Тот, что с целочисленным параметром - скрывается. И даже reintroduce не помогает
          У меня орет о скрытии в обоих случаях :) И reintroduce помогает. Может, просто баг в твоей версии.
            Цитата
            У меня орет о скрытии в обоих случаях


            Орет то оно в обоих. Но в первом случае, procedure Test(I: Integer); virtual; я по прежнему могу вызвать. Врет, собака! :yes-sad:
              Ты его и во втором случае спокойно можешь вызвать. ;)
              Варнинг говорит не о невозможности вызова, а о возможной ошибке. Если бы вызов виртуального метода предка из потомка был невозможен, ты бы предупреждением не отделался!
                Romkin, тут ты не прав. Именно скрывается метод предка (о чем текст варнинга и говорит), что делает невозможным его вызов без приведения типа. Смотри:

                Скомпилируй у себя:
                ExpandedWrap disabled
                    T1 = class(TObject)
                      procedure Test(I: Integer); virtual;
                    end;
                    T2 = class(T1)
                      procedure Test(S: String); virtual;
                    end;
                  ...
                  procedure TForm1.FormCreate(Sender: TObject);
                  var
                    o: T2;
                    s: String;
                    i: Integer;
                  begin
                    o := T2.Create;
                    o.Test(s);
                    o.Test(i);
                    o.Free;
                  end;


                Добавлено
                Именно для таких случаев и была введена reintroduce, чтобы подтвердить, что ты знаешь что делаешь, когда скрываешь виртуальный метод предка.
                  Ндаааааа.... Вот у вас проблемы то... :) override, reintroduce...
                    Цитата
                    Ндаааааа.... Вот у вас проблемы то... override, reintroduce...


                    С выделенным словом как-раз никаких проблем нет. Видимо имелось в виду overload - так эта фича пришла в Delphi из C/C++ ;) В классическом паскале перегружаемых методов и функций не было. Хочешь другой метод - давай ему другое имя. В принципе, эта фича не так уж плоха, да и reintroduce иногда бывает нужен - например, при переопределения конструктора. Так уж принято, что конструктору обычно дается имя Create, а если нам нужен конструктор с другими параметрами, чем виртуальный Create в классе-предке, то не обязательно давать ему другое имя. reintroduce тут спасет.
                    Я не понимаю, зачем reintroduce в данном конкретном случае. Мы ведь ничего не собираемся скрывать, а просто объявить одноименный метод, которы будет доступен наряду с предыдущими объявлениями. Зачем тогда подавлять варнинг о скрытии? Хотя допускаю, что в мои рассуждения закрался "жучок" :)
                      --Ins--, ну а overload где? в #1456 оно есть, а тут вдруг исчезло. Да, reintroduce не имеет особого отношения к overload.
                      Я понял, о чем ты говорил. Компилятор орет невзирая на наличие overload о сокрытии из-за независимости директив. Ведь ты можешь в будущем написать потомка этого потомка, и никто не знает, что тебе там в очередной раз взбредет в голову :D
                        --Ins--, мне, как прожженному плюсовику, все эти рассуждения в принципе странновато читать, т. к., судя по всему, в плюсах система разграничения видимости имен и перегрузки/перекрытия методов в принципе иначе работает. А потому суть решаемой проблемы не совсем понятно. В частности, я всегда предполагал (и продолжаю предполагать), что виртуальность метода играет роль только тогда, когда ты вызываешь метод, имея на руках указатель на базовый класс. Тогда работает полиморфизм времени выполнения. Относительно производного (листового) класса совершенно не важно - является метод виртуальным или нет - в любом случае при вызове механизм виртуализации задействован не будет. Отдельный разговор - это перекрытие/сокрытие имен методов. Но тут виртуальность совершенно не причем, т. к. эти механизмы исключительно compile-time, и управляют видимостью сигнатур методов. По крайней мере, так в С++.
                          Romkin, хорошо, если ты понял, о чем я. Вернемся к примеру
                          ExpandedWrap disabled
                              T1 = class(TObject)
                                procedure Test(I: Integer); virtual;
                              end;
                              T2 = class(T1)
                                procedure Test(S: string); overload; virtual;
                                procedure Test(E: Extended); overload; virtual;
                              end;

                          где метод скрывается действительно. И среда об этом честно предупреждает. У меня два вопроса.
                          1. Почему он скрывается, если в справке явно сказано:
                          Цитата
                          A method can be redeclared using the overload directive. In this case, if the redeclared method has a different parameter signature from its ancestor, it overloads the inherited method without hiding it. Calling the method in a descendant class activates whichever implementation matches the parameters in the call.

                          2. Почему если объявить метод с параметром E, не как Extended, а TObject, ничего не скрывается? В чем принципиальное отличие?

                          Если на первый вопрос ответ "потому что метод виртуальный, а для них все иначе", то следующий вопрос - а какая разница, виртуальный он или нет, если как справедливо заметил Flex Ferrum, эти механизмы (скрытия и вызова метод в зависимости от параметров) исключительно compile-time?
                            Flex Ferrum, да, похоже, иначе все там у вас работает :) В Delphi еще постоянно примешивается RTTI и виртуальные конструкторы. Собственно, для этого и введена директива reintroduce.
                            То есть в Delphi ты можешь прервать и начать заново цепочку наследования виртуального метода, в частности, конструктора, но это не приводит к серьезным последствиям из-за того, что ты всегда можешь явно определить имеющийся класс.
                            То есть, возможен фокус вида
                            ExpandedWrap disabled
                                T1 = class(TObject)
                                  procedure Test(I: Integer); virtual;
                                end;
                                T2 = class(T1)
                                  procedure Test(I: Integer); reintroduce; virtual;
                                end;
                            и оба метода будут достижимы для вызова.
                            Но фактически такое объявление имеет смысл только для конструктора, как показал --Ins--. По крайней мере, другие случаи мне в голову не приходят.
                              Цитата
                              В Delphi еще постоянно примешивается RTTI и виртуальные конструкторы.


                              Дааа, не повезло ребятам... :yes: Кастрированное ООП получается без всего этого. Во всех современных объектно-ориентированных языках без этого никуда
                                Цитата Romkin @
                                и оба метода будут достижимы для вызова.
                                Но фактически такое объявление имеет смысл только для конструктора, как показал --Ins--. По крайней мере, другие случаи мне в голову не приходят.

                                А что значит "достижимы для вызова"? Вызов может быть из двух точек - со стороны базового класса, и со стороны производного. Виртуальность включается только тогда, когда ты вызываешь метод со стороны базового класса "по указателю". Т. е. на самом деле, на руках у тебя может быть один из его производных. Когда ты вызываешь метод для конкретного производного класса, никакой виртуальности нет - все уже известно на этапе компиляции. Так для какого рода вызова эти методы достижимы?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (117) « Первая ... 95 96 [97] 98 99 ...  116 117
                                Закрыто archimed7592 11-03-2008: Лимит страниц. Продолжаем Delphi vs C++



                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1124 ]   [ 15 queries used ]   [ Generated: 26.07.25, 11:54 GMT ]