Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 150 151 [152] 153 154 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#2266
,
|
|
|
|
Это скорее относилось как раз к языкам с GC. Хотя для С++ это weak_ptr. Цитата какого тогда будет поведение b.x, где b.x = a.x? все-таки в примере Игоря мне нравится, что компилятор сообщает о том, что x = a.x делать нельзя (хотя как оказалось иногда можно, а с auto так вообще все выкрутасы становятся бессмысленными =) ) Компилятор ничего не сообщит и ты сможешь работать с полем отдельно от объекта, но ты получишь исключение, если попытаешься обратиться к полю, когда основной объект будет уничтожен... |
|
Сообщ.
#2267
,
|
|
|
|
Цитата D_KEY @ Компилятор ничего не сообщит и ты сможешь работать с полем отдельно от объекта, но ты получишь исключение, если попытаешься обратиться к полю, когда основной объект будет уничтожен... дык это то, что я писал, что меня не устраивает: Цитата в случае же если a.x уничтожиться с a, то в b.x получаем невалидную ссылку => b перед обращением к b.x вынужден будет каждый раз проверять его на валидность =) ну и сама возможность с ним работать Добавлено кстати, DesweR, как бы ты передавал параметры методу: ![]() ![]() a.x("set", [10]); // [10] которые VarArray, я так понимаю? и как бы ты применял найденный по имени метод к этому массиву параметров? |
|
Сообщ.
#2268
,
|
|
|
|
Цитата korvin @ VarArray, я так понимаю? Открытый массив TValue TValue - можно сказать аналог Variant, но для RTTI. Цитата korvin @ и как бы ты применял найденный по имени метод к этому массиву параметров? Средствами RTTI. Собственно реализация: ![]() ![]() 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; Разные вариации создания экземпляра, кому как по вкусу. ![]() ![]() var X: TProxyInvoker; X: TProxyInvokerEx<TInt>; begin X := TProxyInvoker.Create(TInt.Create); X := TProxyInvokerEx<TInt>.Create; X := TProxyInvokerEx<TInt>.Create(TInt.Create); Использование: ![]() ![]() 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. ![]() ![]() 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 с объектом внутри, ничего страшного ситуация реашаема, но это уже завтра. |
|
Сообщ.
#2269
,
|
|
|
|
Мне тут в приват отписали, Ада поддерживает такое искаробки
|
|
Сообщ.
#2270
,
|
|
|
|
Цитата korvin @ Мне тут в приват отписали, Ада поддерживает такое искаробки А можно немного кода с пояснениями(С Адой немного знаком, ну или так думал)? А также может есть примеры полезного применения на практике? |
|
Сообщ.
#2271
,
|
|
|
|
Цитата D_KEY @ А можно немного кода с пояснениями Можно... ![]() ![]() -- Спецификация 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; Ну, и проверяем: ![]() ![]() 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;" работает прекрасно: ![]() ![]() X = 10; Y = 15; Z = 20 [2011-03-16 19:51:27] process terminated successfully (elapsed time: 00.15s) |
|
Сообщ.
#2272
,
|
|
|
|
volvo877, спасибо.
Насколько я понимаю, тут практически тот же принцип, что и у Игоря. А "ссылку" получить на такой объект тоже нельзя? |
|
Сообщ.
#2273
,
|
|
|
|
Цитата D_KEY @ Насколько я понимаю, тут практически тот же принцип, что и у Игоря. а я что-то не заметил в чем общность. надо будет на досуге поиграться с Адой |
|
Сообщ.
#2274
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Насколько я понимаю, тут практически тот же принцип, что и у Игоря. а я что-то не заметил в чем общность. надо будет на досуге поиграться с Адой Ну как же. Закрытый тип с определенными ограничениями. |
|
Сообщ.
#2275
,
|
|
|
|
Цитата D_KEY @ Чтобы можно было получить ссылку, надо специальным образом описывать объекты типа A внутри B. Вот так:А "ссылку" получить на такой объект тоже нельзя? ![]() ![]() type B is record x, y, z : aliased A; end record; . Пока этого не сделаешь - на объект ссылаться нельзя. Ада жестко контролирует подобные вещи... |
|
Сообщ.
#2276
,
|
|
|
|
volvo877,
|
|
Сообщ.
#2277
,
|
|
|
|
Цитата D_KEY @ Ну как же. Закрытый тип с определенными ограничениями. где ж он закрытый, когда в основной программе его можно использовать: ![]() ![]() MyX : A; ? |
|
Сообщ.
#2278
,
|
|
|
|
Надо уже завести тему "Все против всех".
Кстати, мне кажется, или на этом форуме очень мало джавистов? Или им просто некогда в холиварах флудить - надо код писать? |
|
Сообщ.
#2279
,
|
|
|
|
ну тут вроде есть раздел по жабе, наверное им некогда =)
|
|
Сообщ.
#2280
,
|
|
|
|
Почитываю яву вот конкретно сейчас. Там ИМХО и прихвастнуть нечем. Даже хвалёная кроссплатформенность, судя по тенденциям, сходит на нет.
|