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

    Странно... По идее, если мы передаём куда-то ссылку/указатель на Proxy, то подразумевается, что экземпляр A существует. И потом, даже имею эту ссылку/указатель, мы всё равно ничего не можем сделать с x, кроме того, что сами разрешили.

    Тогда почему бы сразу не хранить в public поля типа Int ;) ?

    Цитата
    Цитата D_KEY @
    А ты знаешь как запретить?

    Есть бредовая мысль, которая тебе не понравится ещё больше махинаций с private декларациями :) Надо подумать и почитать.

    Это(эстетическая сторона дела) уже не важно. Я пока вообще не знаю как это сделать. Ну то есть можно поиграться с временными объектами, но тогда не будет ошибок компиляции , и все это будет непрозрачно для клиента.
    Сообщение отредактировано: D_KEY -
      Цитата D_KEY @
      Тогда почему бы сразу не хранить в public поля типа Int?

      Ну, сравни, что мы можем сделать, имея ссылку на Int, и что - имея ссылку на Proxy, если я уберу using Int::set.
      Цитата D_KEY @
      Это(эстетическая сторона дела) уже не важно. Я пока вообще не знаю как это сделать. Ну то есть можно поиграться с временными объектами, но тогда не будет ошибок компиляции , и все это будет непрозрачно для клиента.

      Ну, да, временный объект умрёт и будет хз что во время исполнения...
      Я хотел зайти с другой стороны и сделать каст Proxy в Proxy& приватным. Но сейчас перечитал и вспомнил, что это такой тёмный угол плюсов, что там не только у разных компиляторов противоречия, а даже в самом Стандарте.
      Сообщение отредактировано: MyNameIsIgor -
        Цитата DesweR @
        Тьфу ты, там тоже варнинг, я там не вникал, уже без пяти минут было - домой собирался.

        я не знаю че ты там мутишь, в нормальных системах никаких проблем =) :
        ExpandedWrap disabled
          [ ~/Devel/C++ ] g++ -Wall -o fint fint.cpp
          [ ~/Devel/C++ ] ./fint                    
          x = 10, y = 15, z = 20


        Добавлено
        я-таки в Racket сделал это! =)
        ExpandedWrap disabled
          #lang racket
           
          (define-syntax-rule (hidden outer-name class init ...)
            (begin
              (define inner-name (new class init ...))
              (define/public (outer-name message . params)
                (send-generic inner-name (make-generic class message) . params))))
           
          (define Int
            (class object%
              (define x 0)
              (define/public (get) x)
              (define/public (set v) (set! x v))
              (super-new)))
           
          (define A
            (class object%
              (hidden x Int)
              (hidden y Int)
              (hidden z Int)
              (super-new)))
           
          (define (test)
            (define a (new A))
            (send a x 'set 10)
            (send a y 'set 15)
            (send a z 'set 20)
            (printf "x = ~a, y = ~a, z = ~a\n"
                    (send a x 'get)
                    (send a y 'get)
                    (send a z 'get))
            (with-handlers ((exn:fail? (lambda (e) (printf "~a\n" e))))
              (define x (send a x))
              (printf "shit")))

        ExpandedWrap disabled
          > (test)
          x = 10, y = 15, z = 20
          #(struct:exn:fail:contract:arity procedure x method in A: expects at least 1 argument, given 0 #<continuation-mark-set>)

        простите за оффтоп =)
        Сообщение отредактировано: korvin -
          Цитата korvin @
          я-таки в Racket сделал это! =)

          Можешь пояснить идею?
          И ты скажи, вариант Игоря тебя устраивает или все-таки возможность использовать поля отдельно от объекта тебя не устраивает?
            Цитата D_KEY @
            Можешь пояснить идею?
            И ты скажи, вариант Игоря тебя устраивает или все-таки возможность использовать поля отдельно от объекта тебя не устраивает?

            идея проста: именем hided-поля (outer-name) фактически именуется публичный метод класса A, который принимает на вход имя метода (и другие параметры) и пересылает этот метод внутреннему объекту с именем inner-name класса Int. т.е. в C++ бы этот вызов выглядел наверное примерно так:
            ExpandedWrap disabled
              A.x("set", [10]);
              A.x("get");


            вариант Игоря меня устраивает, я пробовал так:
            ExpandedWrap disabled
              Int x = a.x;

            выдает ошибку:
            ExpandedWrap disabled
              [ ~/Devel/C++ ] g++ -Wall -o fint fint.cpp
              fint.cpp: In function ‘int main()’:
              fint.cpp:36: error: ‘Int’ is an inaccessible base of ‘A::Proxy’

            но я не совсем понял, как ты все-таки вытаскиваешь объект

            Добавлено
            пардоньте мой Английский, правильней наверное hidden, а не hided =)

            Добавлено
            Цитата korvin @
            вариант Игоря меня устраивает

            ну и единственно, что обернуть бы это в шаблон (или может макрос =/), чтоб не описывать каждый раз прокси-класс вручную

            Добавлено
            Цитата korvin @
            ExpandedWrap disabled
              A.x("set", [10]);
              A.x("get");

            конечно хотелось бы, чтобы выглядел по-нормальному, чтоб без магии получения метода по имени (для Racket это нормально, а для C++, имхо, -- магия), ну и + стат. проверка тогда бы была возможна со стороны компилятора
              Цитата korvin @
              A.x("set", [10]);
              A.x("get");

              Т.е. если сделать в таком виде, тебя устроет?

              Добавлено
              Цитата DesweR @
              конечно хотелось бы, чтобы выглядел по-нормальному, чтоб без магии получения метода по имени (для Racket это нормально, а для C++, имхо, -- магия), ну и + стат. проверка тогда бы была возможна со стороны компилятора

              А ну ясно.
                Цитата korvin @
                идея проста: именем hided-поля (outer-name) фактически именуется публичный метод класса A, который принимает на вход имя метода (и другие параметры) и пересылает этот метод внутреннему объекту с именем inner-name класса Int. т.е. в C++ бы этот вызов выглядел наверное примерно так:
                ExpandedWrap disabled
                  A.x("set", [10]);
                  A.x("get");

                Можно в плюсах подумать над указателем на метод, шаблонами с переменным числом аргументов и оборачиваем всего этого в макрос...

                Цитата
                вариант Игоря меня устраивает, я пробовал так:
                ExpandedWrap disabled
                  Int x = a.x;

                выдает ошибку:
                ExpandedWrap disabled
                  [ ~/Devel/C++ ] g++ -Wall -o fint fint.cpp
                  fint.cpp: In function ‘int main()’:
                  fint.cpp:36: error: ‘Int’ is an inaccessible base of ‘A::Proxy’

                но я не совсем понял, как ты все-таки вытаскиваешь объект

                Этот код не работает, потому что от Int Proxy унаследован закрыто.
                Если ты вместо Int поставишь A::Proxy(точнее ссылку на него), то тоже не сработает, но уже потому, что Proxy объявлен как private.
                Но в шаблон ты ссылку на A::Proxy передать передать можешь:
                ExpandedWrap disabled
                  template<typename T, typename DataT>
                  T &assign(T &ref, const DataT &value)
                  {
                      ref.set(value);
                      return ref;
                  }
                   
                  ...
                   
                  int main()
                  {
                    A a;
                    a.x.set(10);
                    a.y.set(15);
                    a.z.set(20);
                    std::cout << "x=" << a.x.get() << " y=" << a.y.get() << " z=" << a.z.get() << std::endl;
                   
                    assign(a.x, 111);
                    assign(a.y, 222);
                    assign(a.z, 333);
                   
                    std::cout << "x=" << a.x.get() << " y=" << a.y.get() << " z=" << a.z.get() << std::endl;
                  }

                Но если тебя устраивает, то и слава богу, - не нужно ломать голову над хаками :)
                Сообщение отредактировано: D_KEY -
                  Цитата DesweR @
                  Т.е. если сделать в таком виде, тебя устроет?

                  попробуй при этом сделать, чтобы внутренний объект и публичный метод с его именем объявлялись одной конструкцией типа
                  ExpandedWrap disabled
                    type
                      ...
                      A = class
                        hidden x :Int;
                      end;

                  тогда как минимум один из вариантов засчитаю. ну и вообще ты предлагай вариант, а там посмотрим, лишним не будет (это и к С++-никам относится)
                    korvin, мне бы все-таки хотелось услышать о практическом применении такого механизма :)
                      Цитата D_KEY @
                      Но если тебя устраивает, то и слава богу, - не нужно ломать голову над хаками :)

                      ну ассерты -- фиг с ними, но через шаблон что, получается таки можно получить ссылку на объект a.x и потом передать ее какому-нибудь другому объекту и он с ней сможет работать?
                        Цитата korvin @
                        Цитата D_KEY @
                        Но если тебя устраивает, то и слава богу, - не нужно ломать голову над хаками :)

                        ну ассерты -- фиг с ними, но через шаблон что, получается таки можно получить ссылку на объект a.x и потом передать ее какому-нибудь другому объекту и он с ней сможет работать?

                        Да, если не будешь явно указывать тип A::Proxy

                        Добавлено
                        Хуже того, работает и через auto :'(
                        ExpandedWrap disabled
                          auto &hack = a.x;
                          hack.set(111);
                          Цитата D_KEY @
                          korvin, мне бы все-таки хотелось услышать о практическом применении такого механизма :)

                          ну я ж сказал, что нехочу, чтоб ссылка на a.x могла храниться еще в каком-нить объекте. в случае языка с GC это означает, что b.x будет жить даже после того, как a умер (тоже самое в случае использования всяких умных указателей в C++), в случае же если a.x уничтожиться с a, то в b.x получаем невалидную ссылку => b перед обращением к b.x вынужден будет каждый раз проверять его на валидность. ну и чисто логически я не хочу, чтобы кто-то где-то обращался к части объекта. каких-то сверхсуперских бонусов это вроде не несет (либо я сам их тоже не знаю =) )
                          Сообщение отредактировано: korvin -
                            Цитата korvin @
                            но через шаблон что, получается таки можно получить ссылку на объект a.x и потом передать ее какому-нибудь другому объекту и он с ней сможет работать?

                            Да, как с Proxy, а не как с Int. Т.е. будет разрешено только то, что разрешили мы.
                              Цитата korvin @
                              Цитата D_KEY @
                              korvin, мне бы все-таки хотелось услышать о практическом применении такого механизма :)

                              ну я ж сказал, что нехочу, чтоб ссылка на a.x могла храниться еще в каком-нить объекте. в случае языка с GC это означает, что b.x будет жить даже после того, как a умер (тоже самое в случае использования всяких умных указателей в C++), в случае же если a.x уничтожиться с a, то в b.x получаем невалидную ссылку => b перед обращением к b.x вынужден будет каждый раз проверять его на валидность. ну и чисто логически я не хочу, чтобы кто-то где-то обращался к части объекта. каких-то сверхсуперских бонусов это вроде не несет (либо я сам их тоже не знаю =) )

                              Хм. А может просто нужно возвращать мягкую ссылку?
                                Цитата D_KEY @
                                Хм. А может просто нужно возвращать мягкую ссылку?

                                я плохо знаком с разными видами ссылок в C++, какого тогда будет поведение b.x, где b.x = a.x? все-таки в примере Игоря мне нравится, что компилятор сообщает о том, что x = a.x делать нельзя (хотя как оказалось иногда можно, а с auto так вообще все выкрутасы становятся бессмысленными =) )
                                Сообщение отредактировано: korvin -
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 149 150 [151] 152 153 ...  494 495


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