На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (495) « Первая ... 159 160 [161] 162 163 ...  494 495  ( Перейти к последнему сообщению )  
> Delphi vs C++ vs C# , ну и Java немножко, где-то ближе к старшему байту номеров страниц
    Цитата korvin @
    гарантирует. согласно логике работы объектов конкретного класса. не нравится -- опирайтесь на некоторый абстрактный класс File, только не надо потом ругаться, если кто-то в потомке переопределит метод Seek и он будет делать "не то, что Вам хотелось", а приведение потомка к предку испортит логику работы потомка

    Ну, так если согласно логики конкретного класса, то с какого перепугу она принимает интерфейс то? Зачем вообще такой ничего не гарантирующий интерфейс нужен?

    Добавлено
    Вообще, господа, я решительно устал. Спасибо за внимание, я кончел.
      Цитата Qraizer @
      D_KEY, я и молчал. Не из-за недостатка агрументов, а из-за отсутствия новых аргументов. Свои я высказал двумя прошлыми постами, только ты не захотел слушать. А сказано было ни более ни менее, чем "движения нет, сказал мудрец брадатый" и дальше ещё три строчки.

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

      Цитата
      Абстрактный класс... интерфейс... концепт... Жизнь, D_KEY, жизнь. Я ж просил попытаться выразить свои доводы не кодом, но документацией. Я ж кода не приводил почему, думаешь?

      Я не только кодом выражал, вначале были слова, которые оказались не поняты. Код - попытка объяснить не словами, а примером.

      Цитата
      Не в коде дело, а в нашедших в нём своё отражение идеях программера. И ещё - в человеческом факторе. Давай я не буду напоминать об интерфейсе операции / для целочисленных аргументов. И твоём желании считать по дефолту все методы константными, кроме явно указанных как наоборот. Тоже утопично, если подумать, и дело совсем не в обратной совместимости.

      Аргументированно. А может все-таки скажешь, почему утопично? Я, знаешь ли, люблю когда мои заблуждения развеивают.
      И не толко методы, но и поля, переменные и т.п. Расскажи, пожалуйста, какие ты видишь проблемы в этом случае?

      Добавлено
      Цитата MyNameIsIgor @
      Вот через две страницы мы всего лишь пришли к пониманию того, что сигнатура и название - это ещё далеко не всё.

      Конечно, не все. Только это никак не влияет на то, что интерфейсу знать ничего больше не нужно.

      Цитата
      Цитата D_KEY @
      То есть концепты можно выкинуть за ненадобностью? Ведь требуем мы именно этого... Заданное название и сигнатуру.

      Не только не выкидывать, но ещё и контракты добавить по соответствующему предложению в комитете.

      Так можешь пояснить, почему, если мы берем два концепта с одинаковым методом, то объект, удовлетворяющий обоим, у тебя опасения не вызывает, а в случае интерфейсов должен быть конфликт?

      Цитата
      Ну, вот, опять двадцать пять... А можно я ещё одну ересь скажу? Я вообще не вижу необходимости иметь в языке "интерфейсы". Меня вполне устроит множественное наследование.

      Это уже другой вопрос. В С++ нет интерфейсов. Вот и подумай, если бы решили вводить интерфейсы, то зачем и какими бы они были?
      Интерфейсы не наследуются. Они подобны концептам.

      Цитата
      А он - обычная тупая сконина, которая должна слушаться, а не палки в колёса вставлять своими альтернативными взглядами на жизнь с далеко идущими выводами.

      Мы говорим о новом для С++ языковом механизме(поскольку в С++ нет интерфейсов). Естественно, что программист будет решать когда и как его использовать.

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

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

      Цитата
      Второй важный момент: мы громогласно заявляем, что реализуем интерфейс, и в то же время скромненько в стороночке молчим о релизуемых нами концептах. Потому что не знаем мы в каких шаблонах будут использовать написанный нами класс. Вопросы соответствия класса концепту будем решать не мы, а тот, кто наш класс использует. Ему специально по такому праздничному случаю и маппинг дали.

      Не соглашусь. Ты, как автор обобщенного кода говоришь, что мне нужны объекты, вот с такими вот "свойствами". И описываешь все это безобразие в концепте. Но вместо концепта ты можешь описать интерфейс. Так в чем разница?

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

      Я выше писал о том, что хотелось бы, чтобы компилятор мог сам увидеть, что класс полностью соответствует интерфейсу. (Создал бы под капотом proxy-объект). То есть было бы поведение, соответствующие шаблонам и концептам, но только в рантайме. Именно это было бы полезно в С++, поскольку "обычные" интерфейсы нам не нужны - бесполезны. Насколько я понял, именно так ведут себя интерфейсы в Go...

      Цитата
      Собственно, всю тему temlates vs generics это и перетирали.

      Это не очень связано с обсуждаемой проблемой.

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

      А я тебе еще раз поясню, что я говорю не об "интерфейсах", в принципе, заменяемых в С++ абстрактными классами.

      Цитата
      Кстати, если есть интерфейс, принимающая его функция и реализующий его класс
      ExpandedWrap disabled
        interface IA
        {
          void f();
        }
         
        void do_something_with_IA(IA ia) { /*какой-то код*/ }
         
        class A : IA
        {
          void f() { /*какой-то код*/ }
        }

      а так же существует код, использующий класс A (сующий его во всякую щель, ожидающую IA), но этому коду ещё известно и о
      ExpandedWrap disabled
        interface IB
        {
          void f();
        }
         
        void do_something_with_IB(IB ib) { /*какой-то код*/ }

      то можно ли запихнуть экземпляр A в do_something_with_IB? А что, по сигнатурам всё проходит! Да и с концептами так делать можно. И вообще у нас поведение по умолчанию - "сливать" "одинаковые" методы.
      Мой ответ - категорическое нет. Не реализовывал автор A интерфейс IB и всё тут. И нефиг за него додумывать.

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

      Добавлено
      Цитата Adil @
      Цитата korvin @
      как это не реализовал, когда реализовал? все методы соответствующих сигнатур на месте => реализовал
      Реализовал интерфейс IB::f()? Да автор IA про него и не слышал и во сне не видел, и понятия не имеет, что должен делать IB::f(). Вот может наглядней так:
      ExpandedWrap disabled
              interface IAL
              {
                int shift(int value);
              }
              
              void do_something_with_IA(IAL ia) { /*какой-то код*/ }
              
              class A : IAL
              {
                int shift(int value) { return value << 1; }
              }
         
              interface IBR
              {
                int shift(int value);
              }
              
              class B : IBR
              {
                int shift(int value) { return value >> 1; }
              }
              
              void do_something_with_IB(IBR ib) { /*какой-то код*/ }
      Боюсь, что код void do_something_with_IB(A a) будет делать что-то не то, что хотелось бы.

      Я уже говорил, что аналогичная проблема в концептах и шаблонах никого не беспокоит ;)

      Добавлено
      Цитата Adil @
      Цитата korvin @
      этого (делать не то, что хотелось бы) можно легко достичь и без интерфейсов.
      Да, но вы то предлагаете, чтобы этого достигал не программист, а компилятор, выбирая shift одного интерфейса при множественном наследовании.

      Adil, тут нет вообще никакого наследования, ни одиночного, ни множественного.

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

      Ну вот... Я только думал вернуться к конструктивному обсуждению(да, я верю, что в данном случае, это возможно).
        Цитата MyNameIsIgor @
        Цитата D_KEY @
        Ну вот... Я только думал вернуться к конструктивному обсуждению(да, я верю, что в данном случае, это возможно).

        Удалено модератором

        Хорошо, договорились :D
        Сообщение отредактировано: Qraizer -
          Цитата korvin @
          то же самое можно сказать из приведенного мной интерфейса
          А это в общем-то и есть интерфейс. Ну да, там вместо завораживающего некоторых слова interface написано class.
          Сообщение отредактировано: trainer -
            Цитата D_KEY @
            То есть было бы поведение, соответствующие шаблонам и концептам, но только в рантайме. Именно это было бы полезно в С++, поскольку "обычные" интерфейсы нам не нужны - бесполезны. Насколько я понял, именно так ведут себя интерфейсы в Go...

            зачем в рантайме? вполне себе в компайл-тайме =) ведь компилятор обладает всей информацией о классе и интерфейсе, соответственно проверку соответствия класса интерфейсу можно проводить во время компиляции. не ну если хочется, то можно и в рантайме, но я бы не стал называть это интерфейсами, дабы не путаться, просто предикатная функция + немножко рефлексии:
            ExpandedWrap disabled
              func implements (x : any, i : interface) {
                  return implements( x.class(), i )
              }
               
              func implements (c : class, i : interface) {
                  for m in i.methods() {
                      if not member( m, c.methods() ) {
                          return false
                      }
                  }
                  return true
              }


            Добавлено
            Цитата trainer @
            А это в общем-то и есть интерфейс. Ну да, там вместо завораживающего некоторых слова interface написано class.

            нет, это класс:
            1) у него есть реализация, которую ты не видишь;
            2) можно инстанциировать экземпляры этого класса.
              Цитата korvin @
              у него есть реализация, которую ты не видишь
              Ну вот когда ты покажешь реализацию, тогда и можно будет сказать о его методах больше, чем я выше написал.
              Цитата korvin @
              можно инстанциировать экземпляры этого класса
              А я говорю - нельзя. Мое слово против твоего. Реализация не приведена - доказать нельзя.
              ExpandedWrap disabled
                #define class interface


              Добавлено
              P.S. А если у меня в C++ конструкторы класса закрыты и соответственно нельзя "инстанциировать экземпляры этого класса" - значит этот класс является интерфейсом?
              Сообщение отредактировано: trainer -
                Цитата korvin @
                зачем в рантайме? вполне себе в компайл-тайме =) ведь компилятор обладает всей информацией о классе и интерфейсе, соответственно проверку соответствия класса интерфейсу можно проводить во время компиляции.

                Проверку осуществлять, конечно, нужно во время компиляции. Я имел в виду позднее связывание.

                Добавлено
                trainer, классы не интерфейсы. И классы от них не наследуют. Именно из-за непонимания этого и идут те разногласия, которые мы наблюдаем последние несколько страниц.
                И в С++ интерфейсов нет, хотя в том виде, в котором они реализованы в таких языках, как C#, Java и Delphi, они в С++ бесполезны.

                Добавлено
                И даже используя #define interface class, ты только введешь в заблуждение клиентов...
                  Цитата trainer @
                  Ну вот когда ты покажешь реализацию, тогда и можно будет сказать о его методах больше, чем я выше написал.

                  зачем? реализация скрыта. инкапсуляция же

                  Цитата trainer @
                  А я говорю - нельзя. Мое слово против твоего. Реализация не приведена - доказать нельзя.

                  опять же, зачем тебе реализация?
                  ExpandedWrap disabled
                    A a;

                  вот тебе создали экземпляр
                    Цитата D_KEY @
                    А может все-таки скажешь, почему утопично? Я, знаешь ли, люблю когда мои заблуждения развеивают.
                    И не толко методы, но и поля, переменные и т.п. Расскажи, пожалуйста, какие ты видишь проблемы в этом случае?
                    Ну почему заблуждение. Отнюдь. Коммунизм вот тоже утопия, но разве это делает его идеи ошибочными? Считай это намёком.
                    Если надоест искать причины.
                    Потому что в C++ нет константных объектов, кроме литералов. Любое упоминание const не более чем обещание, которое теми или иными способами как-то там проверяется, и способы эти не дают абсолютных гарантий. Будь то проверка компилятора, которого при желании легко заткнуть кастом или альясным указателем, или атрибут секции памяти, выставленный ОС, не находящейся под контролем Стандарта языка, или физическое свойство участка памяти, неподконтрольное даже ОС. Зачем тогда лукавить? Поэтому и утопия. Язык такой философии, как у C++, не может себе позволить искажать истинное положение вещей. Вот его дефолтовое отсутствие нареканий не вызывает, ибо отражает реальные характеристики подавляющего большинства исполнительных платформ (а иные платформы, вообще говоря, для C++ просто неинтересны, там больше подойдёт какая-нибудь эзотерика). И если в отдельно взятом месте программист поставит-таки const, то это будет его обещание, а не языка, и язык так уж и быть сделает всё возможное, чтобы поддержать программиста. Чтобы гарантии действительно были, это либо должен был бы быть не C++, либо он должен опираться на железный фундамент в лице исполнительной платформы, что утопично ещё больше.
                    У меня тоже есть утопическое желание, чтобы код (лень выше искать, проще написать)
                    ExpandedWrap disabled
                      struct IA
                      {
                        virtual void f() = 0;
                      };
                       
                      struct IB
                      {
                        virtual void f() = 0;
                      };
                       
                       
                      struct X: IA, IB
                      {
                        void f() {}
                      };
                       
                      X x;
                    не работал. И уже понятно, почему мне так хочется. Видя, что X реализует и IA, и IB, я не понимаю, к какому из них относится X::f(). Я владею документацией и на IA, и на IB, и вижу, что они разные. Хочу вызвать IA::f(), не вызывая IB::f(). Что мне делать? Думаю, если б об интерфейсах в C++ задумывались 25 лет, эта конструкция и не работала бы. Увы, тогда это казалось идеологически подходящим решением.
                      Цитата korvin @
                      вот тебе создали экземпляр
                      А компилятор ответил 'Не могу создать экземпляр класса A - нет доступных конструкторов'. И? Значит это интерфейс?

                      Цитата D_KEY @
                      классы не интерфейсы
                      Я понимаю, что если написано interface - то это завораживающая магия.
                        Все-таки еще раз поясню свою позицию относительно интерфейсов.
                        В языках с множественным наследованием интерфейсы в духе C# и Java будут бесполезны, ибо практически всего того, ради чего они вводились, можно добиться через абстрактные классы и множественное наследование. Можно сказать даже, что интерфейсы в перечисленных выше языках является отчасти костылями, призванными решить те языковые проблемы, которые возникают в результате (нелогичного на мой взгляд) запрета на множественное наследование.
                        Если в языках с множественным наследованием и нужны интерфейсы, то это должен быть более гибкий и полезный в хозяйстве механизм.
                        На мой взгляд, ближе всего к такому понятию подходят концепты(в C++ и частично template constraints в D). Но все-таки отличия есть.
                        Простой пример.
                        ExpandedWrap disabled
                          concept A<typename T>
                          {
                              bool operator()(T &, const std::string &);
                          };
                           
                          template<typename T>
                              where A<T>
                          void f1(const T &obj)
                          {
                              //...
                              if (obj("bla-bla-bla")) {
                                  //...
                              }
                              //...
                          }
                           
                          concept B<typename T>
                          {
                              bool operator()(T &, const std::string &);
                          };
                           
                          template<typename T>
                              where B<T>
                          void g1(const T &obj)
                          {
                              //...
                              if (!obj("bla-bla-bla")) {
                                  //...
                              }
                              //...
                          }
                           
                          interface IA
                          {
                              bool operator()(/* IA& - нужно ли? ,*/ const std::string &);
                              // ...
                          };
                           
                          void f2(IA &obj)
                          {
                              //...
                              if (obj("bla-bla-bla")) {
                                  //...
                              }
                              //...
                          }
                           
                          interface IB
                          {
                              bool operator()(/* IB& - нужно ли? ,*/ const std::string &);
                              // ...
                          };
                           
                          void g2(IB &obj)
                          {
                              //...
                              if (!obj("bla-bla-bla")) {
                                  //...
                              }
                              //...
                          }
                           
                          //...
                           
                          class MyClass
                              // Можем написать:
                              // : public implement IA, // сообщаем, что реализуем интерфейс IA
                              //   public implement A   // сообщаем, что реализуем концепт A
                                                        // (получаем дополнительную проверку при компиляции)
                          {
                          public:
                              bool operator()(const std::string &str)
                              {
                                  //...
                              }
                          };
                           
                          //...
                          MyClass a;
                          f1(a); // ok(класс удовлетворяет концепту A)
                          g1(a); // ok(класс удовлетворяет концепту B)
                          f2(a); // ok(класс удовлетворяет интерфейсу IA - м.б. лучше явный каст)
                          g2(a); // ok(класс удовлетворяет интерфейсу IB - м.б. лучше явный каст)

                        Конечно, такое поведение не всегда идеально, но никто не мешает разрешить разделить реализацию для разных интерфейсов, да и абстрактные классы никто не отменяет.
                        В достаточно мощных языках, где тип является объектом первого рода, возможно соединение концептов и интерфейсов в один языковой механизм, т.к. в этом случае интерфейс может требовать все, что может требовать концепт, в том числе и внутренние типы. Хотя в общем случае возможности концептов все-таки шире.
                        В С++ же эти механизмы объединить в любом случае нельзя, да и не нужно.
                        Относительно пользы таких интерфейсов в С++... На практике это все решается обычными шаблонами и концептами(правда их не будет, что очень печально), хотя в случае динамики, приходится иногда вручную делать адаптеры, даже если сигнатуры и имена совпадают.
                        Прошу прощение у Игоря, если он все-таки решил это прочитать и моя невменяемая простыня вызвала у него приступ тошноты...

                        Добавлено
                        Цитата Qraizer @
                        Цитата D_KEY @
                        А может все-таки скажешь, почему утопично? Я, знаешь ли, люблю когда мои заблуждения развеивают.
                        И не толко методы, но и поля, переменные и т.п. Расскажи, пожалуйста, какие ты видишь проблемы в этом случае?
                        Ну почему заблуждение. Отнюдь. Коммунизм вот тоже утопия, но разве это делает его идеи ошибочными? Считай это намёком.
                        Если надоест искать причины.
                        Потому что в C++ нет константных объектов, кроме литералов. Любое упоминание const не более чем обещание, которое теми или иными способами как-то там проверяется, и способы эти не дают абсолютных гарантий. Будь то проверка компилятора, которого при желании легко заткнуть кастом или альясным указателем, или атрибут секции памяти, выставленный ОС, не находящейся под контролем Стандарта языка, или физическое свойство участка памяти, неподконтрольное даже ОС. Зачем тогда лукавить? Поэтому и утопия. Язык такой философии, как у C++, не может себе позволить искажать истинное положение вещей. Вот его дефолтовое отсутствие нареканий не вызывает, ибо отражает реальные характеристики подавляющего большинства исполнительных платформ (а иные платформы, вообще говоря, для C++ просто неинтересны, там больше подойдёт какая-нибудь эзотерика). И если в отдельно взятом месте программист поставит-таки const, то это будет его обещание, а не языка, и язык так уж и быть сделает всё возможное, чтобы поддержать программиста. Чтобы гарантии действительно были, это либо должен был бы быть не C++, либо он должен опираться на железный фундамент в лице исполнительной платформы, что утопично ещё больше.

                        Спасибо за разъяснения, твоя позиция ясна. Спорить тут не с чем, в том смысле, что ты в принципе прав...

                        Цитата
                        У меня тоже есть утопическое желание, чтобы код (лень выше искать, проще написать)
                        ExpandedWrap disabled
                          struct IA
                          {
                            virtual void f() = 0;
                          };
                           
                          struct IB
                          {
                            virtual void f() = 0;
                          };
                           
                           
                          struct X: IA, IB
                          {
                            void f() {}
                          };
                           
                          X x;
                        не работал. И уже понятно, почему мне так хочется. Видя, что X реализует и IA, и IB, я не понимаю, к какому из них относится X::f(). Я владею документацией и на IA, и на IB, и вижу, что они разные. Хочу вызвать IA::f(), не вызывая IB::f(). Что мне делать? Думаю, если б об интерфейсах в C++ задумывались 25 лет, эта конструкция и не работала бы. Увы, тогда это казалось идеологически подходящим решением.

                        Да, мне тоже кажется, что было бы лучше, если бы в С++ это не работало.

                        Добавлено
                        Цитата trainer @
                        Цитата D_KEY @
                        классы не интерфейсы
                        Я понимаю, что если написано interface - то это завораживающая магия.

                        Нет, дело не в ключевых словах :)
                        Сообщение отредактировано: D_KEY -
                          Цитата trainer @
                          А компилятор ответил 'Не могу создать экземпляр класса A - нет доступных конструкторов'. И? Значит это интерфейс?

                          нет, это значит "нет доступных конструкторов"
                            товарищи С++-ники, вас самих не напрягает наличие кучи шаблонных типов указателей? то, что я насчитал:

                            smart_ptr
                            auto_ptr
                            shared_ptr
                            weak_ptr
                            unique_ptr
                            scoped_ptr
                            intrusive_ptr

                            что-то наверняка упустил
                              Цитата korvin @
                              товарищи С++-ники, вас самих не напрягает наличие кучи шаблонных типов указателей? то, что я насчитал:

                              smart_ptr
                              auto_ptr
                              shared_ptr
                              weak_ptr
                              unique_ptr
                              scoped_ptr
                              intrusive_ptr

                              что-то наверняка упустил

                              Это насчитал не ты, а Роб Пайк, что он и показывал на одной из презентации go.
                              Кстати, поясни, где именно ты их насчитал и для чего каждый нужен ;) ?
                              Сразу скажу, что в стандарте их всего один. В новом стандарте он deprecated, но будут два других из этого списка.
                              Сообщение отредактировано: D_KEY -
                                Цитата D_KEY @
                                Это насчитал не ты, а Роб Пайк, что он и показывал на одной из презентации go.
                                Кстати, поясни, где именно ты их насчитал и для чего каждый нужен ;) ?
                                Сразу скажу, что в стандарте их всего один. В новом стандарте он deprecated, но будут два других из этого списка.

                                хы, значит у нас с ним мысли немного сходятся =)) я считал независимо, я просто перечисли то, что вспомнил по упоминаниям в инете, понятия не имею для чего каждый нужен (это и пугает)

                                в стандарте может и один, но судя по интеу, пользуются многими в зависимости от ситуации
                                Сообщение отредактировано: korvin -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 159 160 [161] 162 163 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.3044 ]   [ 15 queries used ]   [ Generated: 31.07.26, 13:29 GMT ]