На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (495) « Первая ... 338 339 [340] 341 342 ...  494 495  ( Перейти к последнему сообщению )  
> Delphi vs C++ vs C# , ну и Java немножко, где-то ближе к старшему байту номеров страниц
    korvin, мне помнится, что ты был за то, чтобы не делать в рантайме то, что можно сделать во время компиляции ;)
    Или я ошибаюсь?
      или даже так:
      ExpandedWrap disabled
        class Impl<T> {
            public void f() {
                System.out.println("Default");
            }
        }
         
        class A<T> {
            private Impl<T> impl;
            public A(Impl<T> impl) { this.impl = impl; }
            public void use() { impl.f(); }
        }
         
        class Some {}
         
        class SomeImpl<T extends Some> extends Impl<T> {
            public void f() {
                System.out.println("Some");
            }
        }
         
        class Other extends Some {}
         
        class Another extends Some {}
         
        class AnotherImpl<T extends Another> extends Impl<T> {
            public void f() {
                System.out.println("Another");
            }
        }
         
        public class Main {
            public static void main(String[] args) {
                A<String>   stringA = new A<>(new Impl<String>());
                A<Some>       someA = new A<>(new SomeImpl<Some>());
                A<Other>     otherA = new A<>(new SomeImpl<Other>());
                A<Another> anotherA = new A<>(new AnotherImpl<Another>());
                stringA.use();
                someA.use();
                otherA.use();
                anotherA.use();
            }
        }

      ExpandedWrap disabled
        Default
        Some
        Some
        Another


      Добавлено
      Цитата D_KEY @
      korvin, мне помнится, что ты был за то, чтобы не делать в рантайме то, что можно сделать во время компиляции ;)
      Или я ошибаюсь?

      мне помнится, мы тут не этапы обсуждаем
      Сообщение отредактировано: korvin -
        Цитата korvin @
        мне помнится, мы тут не этапы обсуждаем

        А что же?
        Есть полиморфизм статический, есть динамический. В одном случае тебе будет удобнее одно, в другом - другое. Причем они друг другу не мешает и умение их правильно сочетать является одним из главных скиллов для С++ программиста.
        И тут дело даже не в кодировании, а в проектировании. Шаблоны позволяют тебе гибко создавать нужные типы. Вот в твоем коде все построено на композиции объектов, в С++ном же коде будут созданы соответствующие типы. Полистай первую(вроде бы) главу "Современного проектирования на С++"(книга немного устарела, но для нашего обсуждения это не важно), там где идет речь именно о проектировании с использованием политик(стратегий) и характеристик.
        Сообщение отредактировано: D_KEY -
          Цитата D_KEY @
          А что же?

          все остальные особенности, свойства параметров, специализацию вот сейчас обсуждаем.
            korvin, а с этим как быть:

            ExpandedWrap disabled
              template<typename T>
              class A
              {
              public:
                  void f()
                  {
                      data.f();
                  }
                  void g()
                  {
                      data.g();
                  }
               
              private:
                  T data;
              };
               
              struct MyStruct
              {
                  // ...
               
                  void f();
               
                  // ...
               
                  // void g() - нет
              };
               
              //...
               
              A<MyStruct> obj; // Ok
               
              // пока мы не попытаемся вызвать obj.g(),
              // ошибки не будет и нам будет доступно все остальное из A<MyStruct>.
              // Как только мы попытаемся воспользоваться obj.g() мы получим ошибку компиляции.


            Такое поведение связано именно с тем, что мы работает во время компиляции и манипулируем типами, а не объектами.
              а что с этим? да, в Java мы не можем реализовать дженерик-класс частично. зато, если кто-то решит воспользоваться нашим MyStruct, у него не будет проблем, ему не придется писать обертки и юзать их каждый раз, когда ему понадобиться g().

              а связано такое поведение не "с тем, что мы работает во время компиляции и манипулируем типами, а не объектами.", т.к. ничто не мешало запретить такую возможность для шаблонов, просто не захотели/не посчитали нужным/решили, что так удобней
                Цитата korvin @
                ничто не мешало запретить такую возможность для шаблонов

                :blink: Я тебе запрещу! :lol:
                Это правильная и годная вещь.

                Добавлено
                Вот небольшой пример из "Современного проектирования" на эту тему:
                Цитата
                1.8. Факультативные возможности, предоставляемые неполной конкретизацией

                Язык C++ придает стратегиям особую мощь, снабжая их интересным свойством.
                Если функция-член шаблонного класса никогда не используется, она не
                конкретизируется — компилятор вообще игнорирует ее, проверяя лишь синтаксические ошибки.5
                Это дает главным классам возможность задавать и применять факультативные
                свойства классов стратегий. Например, определим функцию-член Switchprototype в
                классе widgetManager.

                ExpandedWrap disabled
                  // Код библиотеки
                   
                  template<template<class> class CreationPolicy>
                  class WidgetManager : public CreationPolicy<Widget>
                  {
                      ...
                      void switchPrototype(widget* pNewPrototype)
                      {
                          CreationPolicy& myPolicy = *this;
                          delete mypolicy.GetPrototype();
                          myPolicy.setPrototype(pNewPrototype);
                      }
                  };

                Возникающий контекст очень интересен.
                • Если пользователь конкретизирует класс WidgetManager с помощью класса
                стратегии Creator, поддерживающей работу с прототипами, можно использовать
                функцию Switchprototype.

                • Если пользователь конкретизирует класс WidgetManager с помощью класса
                стратегии Creator, не поддерживающей работу с прототипами, и попытается
                использовать функцию SwitchPrototype, во время компиляции возникнет ошибка.

                • Если пользователь конкретизирует класс WidgetManager с помощью класса
                стратегии Creator, не поддерживающей работу с прототипами, и не пытается
                использовать функцию Switchprototype, программа считается правильной.

                Все сказанное выше означает, что класс WidgetManager может использовать
                факультативные расширенные интерфейсы, но при этом продолжает правильно работать
                и с интерфейсами, обладающими более бедными возможностями, пока пользователь
                не попытается использовать определенные функции класса WidgetManager.
                Сообщение отредактировано: D_KEY -
                  Цитата D_KEY @
                  Цитата
                  ...пока пользователь
                  не попытается использовать определенные функции класса WidgetManager.

                  и получит жопу. да, очень "правильная и годная вещь"
                    Цитата korvin @
                    и получит жопу

                    Очень оригинальная трактовка статической типизации, в мемориз однозначно.
                    Цитата korvin @
                    а чем тебя не устраивает

                    Переходом в run-time. Если мне будет нужен динамический полиморфизм, я им и воспользуюсь.
                    В реализации могут быть, например, определены флаги, по которым я ориентируюсь, и типы, которые я использую. Как, например, определены итераторы в STL контейнерах.
                    ExpandedWrap disabled
                      template<class T>
                      class Impl
                      {
                      public:
                        static const bool flag = /* что-то там */;
                        typedef T some_type
                        some_type f() { /* реализация */ }
                      };

                    В специализированных специализациях some_type может быть объявлен как угодно.
                    Ну, и потом, я могу захотеть наследовать реализацию
                    ExpandedWrap disabled
                      template<class T>
                      class A : public Impl<T>
                      {
                      };

                    А замещать статический полиморфизм динамическим жутко неэффективно с точки зрения производительности. Особенно доставляют всякие джавошарповские хэшеры и компараторы - тормоза да и только.
                      Цитата korvin @
                      и получит жопу.

                      Почему? Он получит класс, который определяется переданной политикой. Если политика не подразумевает некоторую возможность ее и не будет в целевом классе.
                      Или нужно объяснить что такое политика(стратегия)?
                        Цитата MyNameIsIgor @
                        Очень оригинальная трактовка статической типизации, в мемориз однозначно.

                        интересно при чем тут статическая типизация?

                        Добавлено
                        Цитата MyNameIsIgor @
                        В реализации могут быть, например, определены флаги, по которым я ориентируюсь, и типы, которые я использую. Как, например, определены итераторы в STL контейнерах.
                        ExpandedWrap disabled
                          template<class T>
                          class Impl
                          {
                          public:
                            static const bool flag = /* что-то там */;
                            typedef T some_type
                            some_type f() { /* реализация */ }
                          };

                        В специализированных специализациях some_type может быть объявлен как угодно.

                        в чем проблема-то?
                        ExpandedWrap disabled
                          interface Impl<T> {
                              void f();
                          }
                           
                          class DefaultImpl<T> implements Impl<T> {
                              public static final boolean flag = true;
                              public void f() {
                                  System.out.printf("Default (%s)\n", flag);
                              }
                          }
                           
                          class A<T> {
                              private Impl<T> impl;
                              public A(Impl<T> impl) { this.impl = impl; }
                              public void use() { impl.f(); }
                          }
                           
                          class Some {}
                           
                          class SomeImpl<T extends Some> implements Impl<T> {
                              public void f() {
                                  System.out.println("Some");
                              }
                          }
                           
                          class Other extends Some {}
                           
                          class Another extends Some {}
                           
                          class AnotherImpl<T extends Another> extends SomeImpl<T> {
                              public void f() {
                                  System.out.println("Another");
                              }
                          }
                           
                          public class Main {
                              public static void main(String[] args) {
                                  A<String>   stringA = new A<>(new DefaultImpl<String>());
                                  A<Some>       someA = new A<>(new SomeImpl<Some>());
                                  A<Other>     otherA = new A<>(new SomeImpl<Other>());
                                  A<Another> anotherA = new A<>(new AnotherImpl<Another>());
                                  stringA.use();
                                  someA.use();
                                  otherA.use();
                                  anotherA.use();
                              }
                          }


                        Добавлено
                        Цитата D_KEY @
                        Почему?

                        потому что, он ожидает, что класс реализует g()
                          Цитата korvin @
                          Цитата D_KEY @
                          Почему?

                          потому что, он ожидает, что класс реализует g()

                          Почему?
                            Цитата MyNameIsIgor @
                            Ну, и потом, я могу захотеть наследовать реализацию
                            ExpandedWrap disabled
                              template<class T>
                              class A : public Impl<T>
                              {
                              };

                            и опять в чем проблема?
                            ExpandedWrap disabled
                              class A<T> extends DefaultImpl<T> {
                                  private Impl<T> impl;
                                  public A(Impl<T> impl) { this.impl = impl; }
                                  public void use() { impl.f(); }
                              }


                            Добавлено
                            Цитата D_KEY @
                            Почему?

                            потому что в шаблоне есть g()
                              Цитата korvin @
                              Цитата D_KEY @
                              Почему?

                              потому что в шаблоне есть g()

                              Ну и что? Посмотри пример от Александреску. По-моему там все очевидно для клиента. Кроме того, это будет отражено в документации.
                              Я, честно говоря, не понимаю, в чем проблема.
                                Цитата korvin @
                                в чем проблема-то?

                                А сами не видите? Как я могу получить some_type в вашем коде? Где он у вас вообще? :lol: Или решили дурачка включить? С чего у вас void f()?
                                И, да, на основе flag в плюсах я могу действовать в compile-time. Нужно ли пояснять, что в джаве это невозможно?
                                Цитата korvin @
                                и опять в чем проблема?

                                Не вижу в вашем примере никакого наследования реализации. Изобразите на джаве это
                                ExpandedWrap disabled
                                  template<class T>
                                  class Impl
                                  {
                                  public:
                                    T f();
                                  };
                                   
                                  template<class T>
                                  class A : public Impl<T>
                                  {
                                  };
                                   
                                  class B {};
                                   
                                  template<>
                                  class Impl<B>
                                  {
                                  public:
                                    int f();
                                    B g();
                                  };
                                   
                                  A<B> a;
                                  B b = a.g();
                                  int i = a.f();

                                Цитата korvin @
                                интересно при чем тут статическая типизация?

                                Ну, потому что когда "пользователь попытается использовать определенные функции класса WidgetManager", компилятор сообщит об ошибке. А сделает он это потому, что С++ - статически типизированный язык.
                                В свою очередь, вы этот факт прокомментировали как "получит жопу". Из чего следует вывод, что вы воспринимаете статическую типизацию как жопу.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 338 339 [340] 341 342 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.5347 ]   [ 14 queries used ]   [ Generated: 31.07.26, 11:23 GMT ]