На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (245) « Первая ... 232 233 [234] 235 236 ...  244 245  ( Перейти к последнему сообщению )  
> Есть ли будущее у DELPHI?
    jack128, хочешь приключений, пиши в Дельфи.
    Просто конструкторы (правильнее назвать их инициализаторами) Дельфи это прямые потомки процедур инициализации ещё до-объектного Паскаля. А там никаких ограничений на порядок инициализации естественно не было.

    Вообще-то, если не ошибаюсь, использование виртуальных методов в конструкторах С++ "запрещено" не потому, что работает неправильно, а потому что их правильная работа не гарантируется. То есть при конструировании базового класса реализация не обязательно вызовет методы базового класса, хотя ей никто этого не запрещает. Просто обычно это лишняя работа. Если же сразу устанавливать vtable производного класса, то виртуальные вызовы будут вызывать методы производного класса, для которых ещё нет данных. Кстати, прямые вызовы виртуальных методов из конструктора обычно разрешаются статически.
    И есть много способов обеспечить инициализацию, подобную Дельфи.

    Добавлено
    В каком-то компиляторе такой код
    ExpandedWrap disabled
      class Base {
        virtual void vf() {
          cout << "Конструирование Base" << endl;
        }
        void f() {
          vf()
        }
        Base() {
          f();
        }
      }
       
      class Derived: public Base {
        virtual void vf() {
          cout << "Конструирование Derived" << endl;
        }
        Derived() {
          f();
        }
      }
       
      man() {
        Derived d;
      }

    давал такой вывод
    ExpandedWrap disabled
      Конструирование Base
      Конструирование Derived
    Сообщение отредактировано: amk -
      Цитата jack128 @
      Игорь, я знаю почему это плохо. Я не понимаю, почему доступ к неинициализированным членам через полиморфный вызов из конструктора - плохо. И это запрещено в с++, а вот использование кода #3489 - разрешено ? Я вообще то думал, что компилер обяжет меня метод GetData статиком задекларировать. Но нет.

      Предлагаешь запретить вызов нестатических методов в списке инициализации? Хм.. В принципе, можно было, как мне кажется. Думаю, исторически так сложилось. Хотя возможно, что в некоторых случаях это будет слишком сильным ограничением, которое заставит дублировать код. Но я таких примеров придумать не могу.

      Я так и не понял, какую связь с полиморфными вызовами ты тут видешь.
        Цитата D_KEY @
        Я так и не понял, какую связь с полиморфными вызовами ты тут видешь.

        Я так понимаю, что jack128 говорит о непоследовательности - щепетильное отношения к полиморфным вызовам и наплевательское к обращению к не инициализированным данным.
          Ну тут все-таки разные ..эм.. уровни ответственности. В рассматриваемом случае все происходит в пределах класса, а не размазоно по иерархии. Хотя да, в данном случае лучше было бы как-то предупреждать/ругаться.
            Цитата D_KEY @
            Но я таких примеров придумать не могу.

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

            Хотя понять такой код будет непросто.
            ExpandedWrap disabled
              class UniqueId {
              public:
                UniqueId() id(next_id()) {}
                get_id() {
                  return id;
                }
                ind id;
              private:
                static int next_id() {
                  static int store = 0;
                  return ++store;
                }
              };
               
              class MyObject {
              public:
                MyObject(): name(id()) {} // проще конечно было бы написать name(m_id.get_id())
                                          // но id() здесь не может быть статическим членом
                int id() { return m_id.get_id(); }
                int name() { return m_name; }
              private:
                UniqueId m_id;
                string m_name;
                strng build_name(int id) {
                  ... // Здесь на основе идентификатора генерируем имя
                }
              };
              Цитата D_KEY @
              Предлагаешь запретить вызов нестатических методов в списке инициализации?

              Ну вообще да. Я случайно этот код написал и был сильно удивлен, что компилятор не ругнулся.
                Цитата jack128 @
                Плюсовики, не могли бы вы прокомментировать этот код:
                Не сочти за снобизм, это не придирки к синтетическому примеру.
                Имеем класс с публичным данным. Хм. Это либо не класс, либо данные должны были быть закрыты. В первом случае последующий косяк в производном классе - на совести его автора, во втором - на совести автора базового.
                Производный класс наследует базовый приватно. На лицо желание превратить некласс в класс, что более вероятно. Последнее, надо полагать (иначе зачем это вообще было замышлять), скорее всего из-за (вдруг?) появившихся инвариантов, каковых не было в исходной структуре-классе. Отсюда и косяк автора производного класса: этот класс первый в иерархии, до него классов не было, поэтому он должен заботиться о сохранности своих инвариантов, а значит доступные ему данные, хоть и унаследованные, рассматривать как свои. А всё почему: получать доступ к своим данным посредством своих же методов не глупо, но глупо при этом не учитывать инвариантность, а уж тем более в конструкторах/деструкторах.
                Отсюда, кстати, пошло дурацкое правило во многих CodeStyle-ах на запрет вызова методов из них. Дурацкое - потому что такие баги элементарно отлавливаются на код-ревью, тогда как полный запрет на вызовы методов из конструкторов/деструкторов связывает руки программерам и зачастую вынуждает позволять просачиваться другим, более опасным ошибкам, которые даже на тестировании выявить куда сложнее.
                Цитата jack128 @
                Я не понимаю, почему доступ к неинициализированным членам через полиморфный вызов из конструктора - плохо. И это запрещено в с++
                Во-первых, не запрещено. Полиморфный вызов "всего лишь" не покинет пределов уже сконструированной иерархии (т.е. гарантировано уже работоспособной) и на данный момент конструируемого класса (т.е. полностью под контролем кода конструктора). Во-вторых, как следствие во-первых, полиморфный вызов гарантировано не передаст управление коду, который не готов увидеть мусор на месте объекта. И более того: автор конструктора уверен, что никто не вмешается в процесс конструирования, и он полностью защищён от посягательств извне от не подконтрольного ему кода. Это одна (не единственная) из причин высокой надёжности Плюсовой объектной модели относительно человеческого фактора.
                Цитата jack128 @
                ...а вот использование кода #3489 - разрешено ?
                Тут нет не подконтрольного автору конструктора кода. Тут либо его собственный код, либо унаследованный.
                Цитата amk @
                В каком-то компиляторе такой код...
                ...давал такой вывод...
                Он и должен такой давать.
                  Цитата Qraizer @
                  высокой надёжности Плюсовой объектной модели относительно человеческого фактора

                  Да бросьте! :) Даже я скажу, что C++ больше всех не терпят обезьян :)
                    Впрочем, jack128, я тут же как-то писал подробнее. Чтоб не повторяться...

                    Добавлено
                    Не, даже вот это. Тут интереснее.

                    Добавлено
                    MyNameIsIgor, троллишь? Я не о C++, а о его объектной модели. Это как бы немножечко разные понятия.
                      Цитата Qraizer @
                      MyNameIsIgor, троллишь?

                      Отнюдь.
                      Цитата Qraizer @
                      Я не о C++, а о его объектной модели. Это как бы немножечко разные понятия.

                      А есть ли хоть какая-то разница? Всё равно можно такие низкоуровневые "шалости" творить, что плевать на всю объектную модель.
                        Есть, конечно. Отсутствие жёстких ограничений почти на всё позволяет сделать почти всё. Построить Дельфийную модель в частности, если вдруг приспичит. Ну, почти Дельфийную. Но вот почему-то как-то никто не строит. Я, по крайней мере, никогда не встречал за пределами VCL. Всё дело в опасности что-либо поломать при "нарушении устоев". Чем опаснее последствия, тем сложнее это сделать случайно. К примеру, одно дело спутать публичное и защищённое наследование, другое - порядок инициализации подобъектов.
                        Это уже другая грань С++: не навязывать жёстко ничего, для чего нет категорических абсолютов, однако мотивировать следованию "хорошим традициям". Плюсовая объектная модель не единственно возможная, а значит в некоторых случаях нежелательной. Но это не значит, что язык будет в восторге от ухода в сторону от неё.
                        Сообщение отредактировано: Qraizer -
                          Qraizer, так я об этом же: язык не терпит тех, кто не знает или не умеет. "Хорошие традиции" надо усвоить, правила - запомнить, тонкости - узнать. А после этого всего ещё и не ошибиться. Вот и получается, что человеческий фактор очень сильно влияет.
                          Сообщение отредактировано: MyNameIsIgor -
                            По-моему, мы о разном.

                            Добавлено
                            Поменяй случайно порядок инициализации подобъектов, плз.
                              Цитата Qraizer @
                              Поменяй случайно порядок инициализации подобъектов, плз.

                              Да пожалуйста :D
                              ExpandedWrap disabled
                                struct S
                                {
                                    int i;
                                    S() : i(i) {}
                                };

                              И вот уже у нас i не инициализировано вообще.
                                :facepalm: проехали.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (245) « Первая ... 232 233 [234] 235 236 ...  244 245


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1963 ]   [ 14 queries used ]   [ Generated: 19.07.25, 03:41 GMT ]