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

    я плохо знаком с разными видами ссылок в C++

    Это скорее относилось как раз к языкам с GC. Хотя для С++ это weak_ptr.

    Цитата
    какого тогда будет поведение b.x, где b.x = a.x? все-таки в примере Игоря мне нравится, что компилятор сообщает о том, что x = a.x делать нельзя (хотя как оказалось иногда можно, а с auto так вообще все выкрутасы становятся бессмысленными =) )

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

      дык это то, что я писал, что меня не устраивает:
      Цитата

      в случае же если a.x уничтожиться с a, то в b.x получаем невалидную ссылку => b перед обращением к b.x вынужден будет каждый раз проверять его на валидность

      =) ну и сама возможность с ним работать

      Добавлено
      кстати, DesweR, как бы ты передавал параметры методу:
      ExpandedWrap disabled
        a.x("set", [10]); // [10] которые

      VarArray, я так понимаю?
      и как бы ты применял найденный по имени метод к этому массиву параметров?
        Цитата korvin @
        VarArray, я так понимаю?

        Открытый массив TValue :)
        TValue - можно сказать аналог Variant, но для RTTI.

        Цитата korvin @
        и как бы ты применял найденный по имени метод к этому массиву параметров?

        Средствами RTTI.

        Собственно реализация:
        ExpandedWrap disabled
          uses
            RTTI;
           
          type
            TProxyInvoker = class
            strict private
              FSubject: TObject;
              FRC: TRttiContext;
              FRT: TRttiType;
            public
              constructor Create(const ASubject: TObject);
              destructor  Destroy; override;
              function    Invoke(const AMethodName: string): TValue; overload;
              function    Invoke(const AMethodName: string; const AParams: array of TValue): TValue; overload;
            end;
           
           
            TProxyInvokerEx<T: class, constructor> = class(TProxyInvoker)
            public
              constructor Create; overload;
              constructor Create(const ASubject: T); overload;
            end;
           
           
           
          constructor TProxyInvoker.Create(const ASubject: TObject);
          begin
            FSubject := ASubject;
            FRC := TRttiContext.Create;
            FRT := FRC.GetType(FSubject.ClassInfo);
          end;
           
           
          destructor TProxyInvoker.Destroy;
          begin
            FRC.Free;
            FreeAndNil(FSubject);
            inherited;
          end;
           
           
          function TProxyInvoker.Invoke(const AMethodName: string): TValue;
          begin
            Result := Invoke(AMethodName, []);
          end;
           
           
          function TProxyInvoker.Invoke(const AMethodName: string; const AParams: array of TValue): TValue;
          var
            RM: TRttiMethod;
            RP: TRttiParameter;
            i: integer;
          begin
            RM := FRT.GetMethod(AMethodName);
           
            if not Assigned(RM) then
              raise Exception.Create( Format('Unknown method: %s', [AMethodName]) );
           
            if Length(AParams) > Length(RM.GetParameters) then
              raise Exception.Create( Format('Too many actual parameters.%sMethod prototype:%s%s', [#13#10, #13#10, RM.ToString]) );
           
            if Length(AParams) < Length(RM.GetParameters) then
              raise Exception.Create( Format('Not enough actual parameters.%sMethod prototype:%s%s', [#13#10, #13#10, RM.ToString]) );
           
            i := 0;
            for RP in RM.GetParameters do
            begin
              if RP.ParamType.TypeKind <> AParams[i].Kind then
                raise Exception.Create( Format('Incompatible types: ''%s'' and ''%s''.%sMethod prototype:%s%s', [RP.ParamType.Name, AParams[i].TypeInfo.Name, #13#10, #13#10, RM.ToString]) );
           
              Inc(i);
            end;
           
            Result := RM.Invoke(FSubject, AParams);
          end;
           
           
           
          constructor TProxyInvokerEx<T>.Create;
          begin
            inherited Create(T.Create);
          end;
           
           
          constructor TProxyInvokerEx<T>.Create(const ASubject: T);
          begin
            inherited Create(ASubject);
          end;

        Разные вариации создания экземпляра, кому как по вкусу.
        ExpandedWrap disabled
          var
            X: TProxyInvoker;
            X: TProxyInvokerEx<TInt>;
          begin
            X := TProxyInvoker.Create(TInt.Create);
            X := TProxyInvokerEx<TInt>.Create;
            X := TProxyInvokerEx<TInt>.Create(TInt.Create);


        Использование:
        ExpandedWrap disabled
          type
            TInt = class
            strict private
              FValue: Integer;
            public
              procedure SetInt(const AValue: Integer);
              function  GetInt: Integer;
            end;
           
           
            TC = class
            strict private
              FX: TProxyInvokerEx<TInt>;
              FY: TProxyInvokerEx<TInt>;
              FZ: TProxyInvokerEx<TInt>;
            public
              constructor Create;
              destructor  Destroy; override;
              property X: TProxyInvokerEx<TInt> read FX;
              property Y: TProxyInvokerEx<TInt> read FY;
              property Z: TProxyInvokerEx<TInt> read FZ;
            end;
           
           
           
          function TInt.GetInt: Integer;
          begin
            Result := FValue;
          end;
           
           
          procedure TInt.SetInt(const AValue: Integer);
          begin
            FValue := AValue;
          end;
           
           
           
          constructor TC.Create;
          begin
            FX := TProxyInvokerEx<TInt>.Create;
            FY := TProxyInvokerEx<TInt>.Create;
            FZ := TProxyInvokerEx<TInt>.Create;
          end;
           
           
          destructor TC.Destroy;
          begin
            FreeAndNil(FX);
            FreeAndNil(FY);
            FreeAndNil(FZ);
          end;
           
           
           
          var
            C: TC;
          begin
            try
              C := TC.Create;
           
              C.X.Invoke('SetInt', [1]);
              C.Y.Invoke('SetInt', [2]);
              C.Z.Invoke('SetInt', [3]);
           
              Writeln( C.X.Invoke('GetInt').ToString );
              Writeln( C.Y.Invoke('GetInt').ToString );
              Writeln( C.Z.Invoke('GetInt').ToString );
           
              //C.X.Invoke('GetInt', [1, 2, 3]);
              //C.X.Invoke('SetInt');
              //C.X.Invoke('Some');
           
              Readln;
            except
              on E: Exception do
              begin
                Writeln(E.ClassName, ': ', E.Message);
                Readln;
              end;
            end;
          end.

        ExpandedWrap disabled
          1
          2
          3
           
            //C.X.Invoke('GetInt', [1, 2, 3]);
          Exception: Too many actual parameters.
          Method prototype:
          function GetInt: Integer
           
            //C.X.Invoke('SetInt');
          Exception: Not enough actual parameters.
          Method prototype:
          procedure SetInt(const AValue: Integer)
           
            //C.X.Invoke('Some');
          Exception: Unknown method: Some

        Жаль конечно, что нет статической проверки, но зато можно работать в динамике либыми, заранее не известными, типами объектов :)

        Добавлено
        Заметил пока промах, можно вытащить сам экземпляр TProxyInvoker с объектом внутри, ничего страшного ситуация реашаема, но это уже завтра.
          Мне тут в приват отписали, Ада поддерживает такое искаробки
            Цитата korvin @
            Мне тут в приват отписали, Ада поддерживает такое искаробки

            А можно немного кода с пояснениями(С Адой немного знаком, ну или так думал)? А также может есть примеры полезного применения на практике?
              Цитата D_KEY @
              А можно немного кода с пояснениями

              Можно...
              ExpandedWrap disabled
                -- Спецификация
                package MyTypes is
                 
                   type A is tagged limited private;
                 
                   function get (Obj : A) return Integer;
                   procedure set (Obj : in out A; value : Integer);
                  
                   type B is record
                      x, y, z : A;
                   end record;
                  
                private
                  
                   type A is tagged limited record
                      V : Integer;
                   end record;
                 
                end MyTypes;
                 
                -- Собственно, тело (mytypes.adb)
                package body MyTypes is
                 
                   function get (Obj : A) return Integer is
                   begin
                      return Obj.V;
                   end get;
                 
                   procedure set (Obj : in out A; value : Integer) is
                   begin
                      Obj.V := value;
                   end set;
                 
                end MyTypes;


              Ну, и проверяем:
              ExpandedWrap disabled
                   with ada.Text_IO; use Ada.Text_IO;
                   with MyTypes; use MyTypes;
                      
                   procedure Main is
                      test_obj : B;
                      MyX : A; -- Попытаемся получить объект сюда
                   begin
                      MyX := test_obj.x;  -- Облом-с, лимитированный тип не копируется, компиляция останавливается...
                      test_obj.x.set (10);  -- А вызвать метод - пожалуйста
                      test_obj.y.set (15);
                      test_obj.z.set (20);
                        
                      Put_Line ("X =" & Integer'Image (test_obj.x.get) &
                                "; Y =" & Integer'Image (test_obj.y.get) &
                                "; Z =" & Integer'Image (test_obj.z.get));
                   end Main;


              Без строки "MyX := test_obj.x;" работает прекрасно:
              ExpandedWrap disabled
                X = 10; Y = 15; Z = 20
                [2011-03-16 19:51:27] process terminated successfully (elapsed time: 00.15s)
              Сообщение отредактировано: volvo877 -
                volvo877, спасибо.
                Насколько я понимаю, тут практически тот же принцип, что и у Игоря.
                А "ссылку" получить на такой объект тоже нельзя?
                  Цитата D_KEY @
                  Насколько я понимаю, тут практически тот же принцип, что и у Игоря.

                  а я что-то не заметил в чем общность. надо будет на досуге поиграться с Адой
                    Цитата korvin @
                    Цитата D_KEY @
                    Насколько я понимаю, тут практически тот же принцип, что и у Игоря.

                    а я что-то не заметил в чем общность. надо будет на досуге поиграться с Адой

                    Ну как же. Закрытый тип с определенными ограничениями.
                      Цитата D_KEY @
                      А "ссылку" получить на такой объект тоже нельзя?
                      Чтобы можно было получить ссылку, надо специальным образом описывать объекты типа A внутри B. Вот так:

                      ExpandedWrap disabled
                           type B is record
                              x, y, z : aliased A;
                           end record;

                      . Пока этого не сделаешь - на объект ссылаться нельзя. Ада жестко контролирует подобные вещи...
                        volvo877, :good:
                          Цитата D_KEY @
                          Ну как же. Закрытый тип с определенными ограничениями.

                          где ж он закрытый, когда в основной программе его можно использовать:
                          ExpandedWrap disabled
                            MyX : A;

                          ?
                            Надо уже завести тему "Все против всех".
                            Кстати, мне кажется, или на этом форуме очень мало джавистов? Или им просто некогда в холиварах флудить - надо код писать? :)
                              ну тут вроде есть раздел по жабе, наверное им некогда =)
                                Почитываю яву вот конкретно сейчас. Там ИМХО и прихвастнуть нечем. Даже хвалёная кроссплатформенность, судя по тенденциям, сходит на нет.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 150 151 [152] 153 154 ...  494 495


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