На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (6) « Первая ... 3 4 [5] 6  все  ( Перейти к последнему сообщению )  
> Каким должен быть С++? , Ваше мнение
    Цитата MyNameIsIgor @
    всё должно быть compile-time, imho

    Это не всегда возможно. Каким образом процедура test может получить фактический класс значения переменной x из статической информации о ней?
    Сообщение отредактировано: korvin -
      Цитата korvin @
      Цитата MyNameIsIgor @
      всё должно быть compile-time, imho

      Это не всегда возможно. Каким образом процедура test может получить фактический класс значения переменной x из статической информации о ней?

      Да, возможностей меньше, но рефлексия во время исполнения слабо вяжется с нишей языка. Если они так сильно нужны, то можно взять другой язык.
      Ну, а test в данном случае можно сделать шаблоном.
        Цитата MyNameIsIgor @
        Ну, а test в данном случае можно сделать шаблоном

        Каким образом это поможет, если я захочу применить ее (в цикле) к коллекции [Parent*], в которой могут находиться элементы любого дочернего класса?

        По-моему было бы неплохо иметь возможность создавать (локальные, временные) расширения классов без необходимости в рантайме создавать копию коллекции (в отличие от использования субклассов), типа того:

        ExpandedWrap disabled
          extension Test
          {
              class Parent
              {
              public:
                  virtual void describe()
                  {
                      ^describe(); // вызов оригинального метода Parent::describe
                      cout << " extension Test";
                  }
              };
              
              class Child
              {
              public:
                  virtual void describe()
                  {
                      cout << "Child extension Test";
                  }
              };
          };
           
          void
          test(vector<Parent> xs)
          {
              extend xs : Test;
              for (auto x : xs) {
                  x->describe();
                  cout << endl;
              }
          }


        Только я не представляю как это можно (или насколько сложно) сделать потокобезопасно.
        Сообщение отредактировано: korvin -
          Цитата korvin @
          Каким образом это поможет, если я захочу применить ее (в цикле) к коллекции [Parent*], в которой могут находиться элементы любого дочернего класса?

          В случае run-time созданной коллекции, конечно, никаким.
          Но с помощью статической рефлексии можно сгенерировать информацию, которая будет использовать во время исполнения. Это потребует лишних телодвижений от программиста со всякой регистрацией и тому подобным, но лучше соответствует духу языка.
          Цитата korvin @
          По-моему было бы неплохо иметь возможность создавать (локальные, временные) расширения классов без необходимости в рантайме создавать копию коллекции (в отличие от использования субклассов), типа того:

          Должен сказать, что не осилил что это и о чём ты хочешь сказать :-)
            Цитата MyNameIsIgor @
            Контракты. Тоже хочу 8-)

            Ссылка, насколько я понимаю, не туда.
              Цитата MyNameIsIgor @
              Должен сказать, что не осилил что это и о чём ты хочешь сказать :-)

              Ну вот смотри, вернемся к цели использования рефлексии, допустим в примере с test это могло бы быть что-то вроде:

              ExpandedWrap disabled
                class Parent
                {
                public:
                    virtual void describe()
                    {
                        cout << "Parent";
                    }
                };
                 
                class Child : public Parent
                {
                public:
                    virtual void prefix()
                    {
                        cout << "\t";
                    }
                    virtual void describe()
                    {
                        cout << "Child";
                    }
                };
                 
                void
                test(Parent *x)
                {
                    // синтаксис условный
                    if (RTTI::supports(x, RTTI::class<Child>()))
                        RTTI::cast<Child>(x)->prefix();
                    x->describe();
                    cout << endl;
                }


              что с точки зрения ООП как бы не очень хорошо, ведь для такого и существуют классы (точнее ad-hoc полиморфизм и data directed programming), чтобы специализированный код выбирался автоматически по типу данных без всяких if'ов.

              Вообще более общий случай -- проверка наличия метода void prefix(), но не будем усложнять.

              Можно создать субкласс Child
              ExpandedWrap disabled
                class ChildExt : public Child
                {
                public:
                    virtual void describe()
                    {
                        prefix();
                        Child::describe(&this);
                    }
                };

              или прокси
              ExpandedWrap disabled
                class ChildProxy : public Child
                {
                private:
                    Child *original;
                public:
                    virtual void describe()
                    {
                        original->prefix();
                        original->describe();
                    }
                    virtual Child* getOriginal()
                    {
                        return original;
                    }
                };


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

              Вот если бы мы могли локально, временно изменять классы, не затрагивая сами объекты, тогда бы все эти проблемы были бы решены.

              ExpandedWrap disabled
                extension Test
                {
                    class Child {
                    public:
                        virtual void describe()
                        {
                            prefix();
                            ^descibe(); // original
                        }
                    }
                };


              Тогда бы test осталась бы максимально простой, никаких "дум" где и как вставить преобразование объектов Child к ChildExt или ChildProxy, почти никаких накладных расходов на рантайм

              ExpandedWrap disabled
                void
                test(Parent *x)
                {
                    x->describe();
                    cout << endl;
                }
                 
                    ...
                    extend Test; // область действия определяется как и для всего остального -- по области видимости
                    for (Parent *x : xs)
                        test(x);
                    ...


              Вообще это похоже на динамические переменные CL, только применяется к классам.
                Цитата MyNameIsIgor @
                Библиотеками такое не реализовать, тем более эффективно.
                Я попробовал. Два полиморфных вызова на каждый позднесвязываемый параметр. Думаю, ещё эффективнее не выйдет.

                Добавлено
                Ладно, будет сам мой дембельский аккорд. Всё равно за три дня не успею под C++11 перенести, раз до сих пор так и не собрался. А скоро уже и не надо будет, ибо будут испаропки.
                  Цитата D_KEY @
                  Цитата MyNameIsIgor @
                  Контракты. Тоже хочу 8-)

                  Ссылка, насколько я понимаю, не туда.

                  Исправил.

                  Добавлено
                  Цитата Qraizer @
                  Я попробовал. Два полиморфных вызова на каждый позднесвязываемый параметр. Думаю, ещё эффективнее не выйдет.

                  Я помню их - там необходима регистрация в одном месте, что неприемлемо. Это во-первых.
                  Во-вторых, если мы оставляем подобную регистрацию, то эффективнее можно по тому же принципу, что описан у Страуструпа.
                    Эффективнее можно при поддержке языка. Я говорил о библиотеке.
                      Цитата Qraizer @
                      Эффективнее можно при поддержке языка. Я говорил о библиотеке.

                      Я тоже. Таблицу, про которую пишет Бьярн, можно сформировать, если регистрация всего происходит в одном месте.
                        korvin, правильно ли я понимаю, что таким "расширением класса" ты в данном случае говоришь "для всех Child в этой коллекции вызови prefix перед describe"?
                          Цитата MyNameIsIgor @
                          правильно ли я понимаю, что таким "расширением класса" ты в данном случае говоришь "для всех Child в этой коллекции вызови prefix перед describe"?

                          Да.
                            Цитата korvin @
                            Цитата MyNameIsIgor @
                            правильно ли я понимаю, что таким "расширением класса" ты в данном случае говоришь "для всех Child в этой коллекции вызови prefix перед describe"?

                            Да.

                            Ну, тогда это возможно реализовать. По семантике это как раз предложение от Страуструпа и Ко по мультиметодам :)
                            ExpandedWrap disabled
                              void test(virtual Parent* p)
                              {
                                p->describe();
                              }
                               
                              void test(virtual Child* p)
                              {
                                p->prefix();
                                p->describe();
                              }
                               
                              for(Parent* p : vector)
                                test(p);

                            Конечно, решить общий случай проверки наличия метода с заданным именем и сигнатурой это не позволяет.
                              Цитата MyNameIsIgor @
                              По семантике это как раз предложение от Страуструпа и Ко по мультиметодам

                              Да, думаю, так лучше.

                              Цитата MyNameIsIgor @
                              Конечно, решить общий случай проверки наличия метода с заданным именем и сигнатурой это не позволяет.

                              Ну, мой огород этого тоже не позволяет, но само по себе решение этой небольшой проблемы с test покрывает 99% случаев использования рантайм-рефлексии, ИМХО.

                              Добавлено
                              Вообще для упрощения можно было бы ограничиться для начала не мультиметодами, а просто "внешними" методы.
                                Цитата korvin @
                                Вообще для упрощения можно было бы ограничиться для начала не мультиметодами, а просто "внешними" методы.

                                Имеешь в виду возможность добавления в класс методов без его изменения? Типа этого? Просто это рассматривается как изменение на уровне синтаксиса. А документ по мультиметодам скорее сосредоточен на способе их реализации, и для одного параметра вызов foo(bar) полностью эквивалентен существующим виртуальным методам bar.foo()
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.1084 ]   [ 14 queries used ]   [ Generated: 27.07.26, 06:56 GMT ]