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

    Мне кажется - это не недостаток, а фишка!

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

    Вместо наследования - применяем агрегацию! См. сравнимый по функционалу код:

    C++:

    ExpandedWrap disabled
      #include <iostream>
      using namespace std;
       
      struct A {
        int a;
        A(int x);
        virtual void print();
      };
       
      struct B : A {
        int b;
        B(int x, int y);
        void print() override;
      };
       
      struct C : B {
        int c;
        C(int x, int y, int z);
        void print() override;
      };
       
      A::A(int x):a(x) {
      }
       
      void A::print() {
        cout << a << endl;
      }
       
      B::B(int x, int y):A(x),b(y) {
      }
       
      void B::print() {
        A::print();
        cout << b << endl;
      }
       
      C::C(int x, int y, int z):B(x,y),c(z) {
      }
       
      void C::print() {
        B::print();
        cout << c << endl;
      }
       
      int main() {
        C c = {1,2,3};
        c.print();
        return 0;
      }

    Rust:

    ExpandedWrap disabled
      use std::io::stdin;
       
      struct A {
        a: u32    
      }
       
      struct B {
        a: A,
        b: u32
      }
       
      struct C {
        b: B,
        c: u32
      }
       
      trait Print {
        fn print(&self);
      }
       
      impl Print for A {
        fn print(&self) {
          println!("{}",self.a)  
        }    
      }
       
      impl Print for B {
        fn print(&self) {
          self.a.print();
          println!("{}",self.b)  
        }    
      }
       
      impl Print for C {
        fn print(&self) {
          self.b.print();
          println!("{}",self.c)  
        }    
      }
       
      fn main() {
        let C = C{b:B{a:A{a:1},b:2},c:3};
        C.print();
      }


    Если говорить про вкусовщину - меня код Раст радует больше! :yes:
      А что тебе мешало в C++ написать примерно так же?
      ExpandedWrap disabled
        #include <iostream>
        using namespace std;
         
        struct Print {
            virtual void print() = 0;
        };
         
        struct A : Print {
          int a;
          A(int x);
          void print() override;
        };
         
        struct B : Print {
          A a;
          int b;
          B(int x, int y);
          void print() override;
        };
         
        struct C : Print {
          B b;
          int c;
          C(int x, int y, int z);
          void print() override;
        };
         
        A::A(int x):a(x) {
        }
         
        void A::print() {
          cout << a << endl;
        }
         
        B::B(int x, int y):a(x),b(y) {
        }
         
        void B::print() {
          a.print();
          cout << b << endl;
        }
         
        C::C(int x, int y, int z):b(x,y),c(z) {
        }
         
        void C::print() {
          b.print();
          cout << c << endl;
        }
         
        int main() {
          C c = {1,2,3};
          c.print();
          return 0;
        }


      Добавлено
      Цитата JoeUser @
      И это упрощает в некотором смысле архитектуру. Не нужно заботиться, что, где, кого перекрывает, какие классы (при множественном наследовании) могут нечаянно включиться N или даже M! раз ...

      В C++ ты можешь организовать свою архитектуру так же. А вот в Rust выбора нет :)
        Цитата D_KEY @
        А что тебе мешало в C++ написать примерно так же?

        Не мешало. Наоборот - я хотел от наследования С++ перейти к агрегации на Расте, без потери функционала.

        Цитата D_KEY @
        В C++ ты можешь организовать свою архитектуру так же. А вот в Rust выбора нет :)

        Вот тут давай уточнять! :lol: Правильнее бы было сказать, имхо, так: "В C++ ты можешь организовать свою C++ - шную архитектуру так же. А вот в Rust выбора нет".

        Добавлено
        D_KEY, и да ... твой код не эквивалентен "растовскому"! Я сперва тоже приплел виртуальные функции, потом подумал, что на 3 структурах можно и без них.
          Цитата JoeUser @
          D_KEY, и да ... твой код не эквивалентен "растовскому"! Я сперва тоже приплел виртуальные функции, потом подумал, что на 3 структурах можно и без них.

          Разница только в том, что в Rust отвязаны структуры и impl. Ты про это?
            Цитата D_KEY @
            Ты про это?
            Нет. Наличие виртуальных Функций - это уже наличие VMT. А это не по фэн-шую :)
              Цитата JoeUser @
              Цитата D_KEY @
              Ты про это?
              Нет. Наличие виртуальных Функций - это уже наличие VMT. А это не по фэн-шую :)

              Ты думаешь, что Impl'ы как-то иначе устроены? :)
                Цитата D_KEY @
                Ты думаешь, что Impl'ы как-то иначе устроены?

                Думаю да. Иначе бы я не читал этого ;)
                  Цитата JoeUser @
                  Цитата D_KEY @
                  Ты думаешь, что Impl'ы как-то иначе устроены?

                  Думаю да. Иначе бы я не читал этого ;)

                  Так оттуда же(про динамическую диспетчерезацию):
                  Цитата
                  However, this comes at the cost of requiring slower virtual function calls, and effectively inhibiting any chance of inlining and related optimisations from occurring.


                  Добавлено
                  А в Representation заглядывал?

                  Добавлено
                  Цитата
                  The methods of the trait can be called on a trait object via a special record of function pointers traditionally called a 'vtable' (created and managed by the compiler).
                    D_KEY, э не ... так не пойдет! :lol: Давай пруф из доков, где говорится, что любая реализация "методов" посредством блока impl породжает одиночную дичпетчеризацию (через VMT). Иначе я моя твоя не понимать. И это ... учитывай, что книгу по Расту я прочел только один раз, в меру своей внимательности! Считай - махровый нубас! :lol:
                      JoeUser, смотри в раздел Representation по твоей ссылке. Там даже та же терминология используется(vtable).
                        Цитата D_KEY @
                        про динамическую диспетчерезацию

                        Погоди ... так это вырвано из контекста??? А при статической (как у меня в примере)? Там тоже Раст будет VMT (ну или что-то подобное) городить??? Я в это не поверю! :-?

                        Добавлено
                        Цитата D_KEY @
                        ам даже та же терминология используется(vtable).

                        Ну да - для динамической диспетчеризации! Но откуда такое обобщение:

                        Цитата D_KEY @
                        Ты думаешь, что Impl'ы как-то иначе устроены?


                        ??? Читается как "всегда" :-?
                          В примере JoeUser-а же компилятору точный тип известен, так что никакого виртуального вызова быть не должно. Хотя изначально разговор был про наличие VMT - возможно, компилятор эту таблицу всё же генерирует :)
                          Сообщение отредактировано: OpenGL -
                            Цитата OpenGL @
                            возможно, компилятор эту таблицу всё же генерирует

                            Покажите, что это всегда "да" - и я забуду про Раст :lol:

                            Скрытый текст
                            По поводу терминологии. Я применил термин "агрегация" как альтернатива наследованию. Покак еще не осознал глубину всех глубин. Возможно был не прав. Есть еще альтернативный вариант - "композиция". Терки об этом тут. Будем еще почитать! 8-)
                              Для приведенного плюсового кода компилятор вполне может так же сгенерировать код без обращения к vtable. Это же вопрос оптимизации.
                              В C++ для статической диспетчерезации вообще будет достаточно обычных перегруженных функций в данном примере :) В более сложных случаях - шаблоны.

                              Добавлено
                              Но вообще подход Rust здравый. Я помню еще давно в дельфийских холиварах как-то поднимал вопрос о том, зачем, по большому счету разделять понятия статических "концептов" и динамических "интерфейсов".
                                Цитата JoeUser @
                                Покажите, что это всегда "да" - и я забуду про Раст

                                А почему не должен создавать? Если ты создал трейт, который является trait object-ом, то по-моему вполне естественно ожидать, что ты будешь использовать его именно в таком контексте. Если это не так (что, кстати, в расте не редкость), то в общем-то только и остаётся, что надеяться на оптимизатор, который сообразит, что виртуальные вызовы ты не используешь.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (16) 1 [2] 3 4 ...  15 16 все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0507 ]   [ 16 queries used ]   [ Generated: 18.04.24, 23:37 GMT ]