Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.12.21;
Скачать: [xml.tar.bz2];

Вниз

класс, который не нужно создавать.   Найти похожие ветки 

 
@!!ex ©   (2008-11-10 17:48) [0]

Можно ли както сделать, чтобы класс создавался и удалялся автоматически, без явного TClass.Create(); ?

тоесть:

TVector = class;

Обычно делаю так:
Function ();
var
 v:TVector;
begin
 v:=TVector.Create();
 v:=a+b;
 v.free();
end;


А хочется так:
Function ();
var
 v:TVector;
begin
 v:=a+b;
end;


 
clickmaker ©   (2008-11-10 17:50) [1]

> А хочется так:

переходи на С++ :)


 
@!!ex ©   (2008-11-10 19:17) [2]

Не актуально. Уже на С++.
Но есть проекты и на дельфи... вот и пытаюсь придумать что делать. :((


 
Джо ©   (2008-11-10 20:03) [3]

С созданием ничем не поможешь, нужно будет создавать :)
А с удалением проще — интерфейсы.


 
@!!ex ©   (2008-11-10 20:11) [4]

Собственно откуда желание.
Есть два типа TVector4f и TMatrix4x4f. Оба - рекорды.
Оба типа очень активно используются.
Матрица умеет усножать себя на вектор оператором.
Сейчас понадобилось научить вектор умножать себя на матрицу. Отсюда возникла проблема:
http://delphimaster.net/view/2-1226325610/

Вроде бы проблемы нет, если использовать класс вместо рекорда. Но!
Но вектора и матрицы разбросаны по всему коду.
Если я переделаю все на классы - придется везде бегать вставлять Create(); Free;
Отсюда:
1) Не факт что я где-то что-то не пропущу
2) Создавать и удалять явно часто используемые простые типы - это не совсем умно с точки зрения читабельности кода.


 
oxffff ©   (2008-11-10 21:08) [5]

TSomeClass<T: class,constructor> = record
 public
 class operator Implicit(const AValue: TSomeClass<T>): T;
 class operator Add(const AValue:TSomeClass<T>;AValue2:TSomeClass<T>): T;
 end;

class operator TSomeClass<T>.Implicit(const AValue: TSomeClass<T>): T;
begin
showmessage("Implicit cast");
Result:=T.create;
end;

class operator TSomeClass<T>.Add(const AValue:TSomeClass<T>;AValue2:TSomeClass<T>): T;
begin
showmessage("Binary op");
exit(T.create);
end;

procedure TForm2.FormCreate(Sender: TObject);
var a,b:TSomeClass<TObject>;
   c:Tobject;
begin
c:=a+b;
c:=a;
end;


 
@!!ex ©   (2008-11-10 21:25) [6]

> [5] oxffff ©   (10.11.08 21:08)

2009? :))
У меня TDE...


 
oxffff ©   (2008-11-10 21:26) [7]


> oxffff ©   (10.11.08 21:08) [5]


Усложняем задачу, делая автоматическое освобождение объектов.

Get Ready!!!

TDemoObject=class
procedure BeforeDestruction;override;
end;

TObjectHandle<T: class> = class(TInterfacedObject, TFunc<T>)
 private
   FValue: T;
 public
   constructor Create(AValue: T);
   destructor Destroy; override;
   function Invoke: T;
 end;

TSomeClass<T: class,constructor> = record
 public
 class operator Implicit(const AValue: TSomeClass<T>): TFunc<T>;
 class operator Add(const AValue:TSomeClass<T>;AValue2:TSomeClass<T>): TFunc<T>;
 end;

procedure TDemoObject.BeforeDestruction;
begin
showmessage("Этот пройдешь как дети в школу");
inherited;
end;

class operator TSomeClass<T>.Implicit(const AValue: TSomeClass<T>): TFunc<T>;
begin
showmessage("Implicit cast");
exit(TObjectHandle<T>.create(T.create));
end;

class operator TSomeClass<T>.Add(const AValue:TSomeClass<T>;AValue2:TSomeClass<T>): TFunc<T>;
begin
showmessage("Binary op");
exit(TObjectHandle<T>.create(T.create);
end;

procedure TForm2.FormCreate(Sender: TObject);
var a,b:TSomeClass<TDemoObject>;
   c:TFunc<TDemoObject>;
begin
c:=a+b;
c:=a;
end;

constructor TObjectHandle<T>.Create(AValue: T);
begin
 FValue := AValue;
end;

destructor TObjectHandle<T>.Destroy;
begin
 FValue.Free;
end;

function TObjectHandle<T>.Invoke: T;
begin
 Result := FValue;
end;


 
oxffff ©   (2008-11-10 21:30) [8]


> procedure TForm2.FormCreate(Sender: TObject);
> var a,b:TSomeClass<TDemoObject>;
>    c:TFunc<TDemoObject>;
> begin
> c:=a+b;
> c:=a;
> end;


Ну естественно можно С.Classname и т.д.


 
oxffff ©   (2008-11-10 22:48) [9]


> @!!ex ©   (10.11.08 21:25) [6]
> > [5] oxffff ©   (10.11.08 21:08)
>
> 2009? :))
> У меня TDE...


Переходи на 2009. См. [7].


 
jack128_   (2008-11-10 23:11) [10]


> TObjectHandle<T: class> = class(TInterfacedObject, TFunc<T>)

а что означает эта запись??

TFunc<T> объявлен вот так:
 TFunc<TResult> = reference to function: TResult;

что то не вьеду, как класс может наследоваться от анонимного метода??


 
@!!ex ©   (2008-11-11 00:11) [11]

> Переходи на 2009.

две штуки баксов на покупку не одолжите? :)))


 
Loginov Dmitry ©   (2008-11-11 00:19) [12]

может все-таки с .Create() будет проще?)))


 
oxffff ©   (2008-11-11 08:38) [13]


> jack128_   (10.11.08 23:11) [10]
>
> > TObjectHandle<T: class> = class(TInterfacedObject, TFunc<T>)
>
> а что означает эта запись??
>
> TFunc<T> объявлен вот так:
>  TFunc<TResult> = reference to function: TResult;
>
> что то не вьеду, как класс может наследоваться от анонимного
> метода??


Анонимный метод это интерфейс.


 
oxffff ©   (2008-11-11 08:43) [14]


> jack128_   (10.11.08 23:11) [10]


Если интересно историю можешь посмотреть мою переписку c Barry Kelly в его блоге.

Сначало было

http://barrkel.blogspot.com/2008/11/reference-counted-pointers-revisited.html

после переписки

Sergey Antonov aka oxffff said...
@Barry

perfectly, since anonymous method has Ref counting semantic and is used by outer consumer, there is no need in inner shared TSmartPointerController.
So we can remove 2 extra objects.

он предложил этот способ


> There was a little to and fro in the comments on yesterday"s
> post on more fluent smart pointers


http://barrkel.blogspot.com/2008/11/somewhat-more-efficient-smart-pointers.html


 
jack128_   (2008-11-11 18:32) [15]


> Анонимный метод это интерфейс.

Ха.  Блин, имхо - не правельно.  ТОчнее то что анонимные методы - как интефейсы реализованы - это понятно, но лично мне не ясно, нафиг эту внутреннюю кухню наружу выносить..


> он предложил этот способ

не сильно лудше его самого первого смарт поинтера, если чесно:
Новый вариант:
var
 Obj: TFunc<TObject>
begin
 Obj := THandleObject<TObject>.Create(TObject.Create);
end;


Старый вариант:
var
 Obj: TObject;
begin
 Obj := TSmatPointer<TObject>.Create(TObject.Create).Value;
end;


 
Правильный$Вася   (2008-11-11 18:47) [16]


> Есть два типа TVector4f и TMatrix4x4f. Оба - рекорды.Оба
> типа очень активно используются.Матрица умеет усножать себя
> на вектор оператором.Сейчас понадобилось научить вектор
> умножать себя на матрицу.

можешь сделать функцию, что мешает?


 
@!!ex ©   (2008-11-11 19:15) [17]

> [16] Правильный$Вася   (11.11.08 18:47)

Так и сделал.
Мешает то, что код превращается в свалку.

Сравните:
Function GetNormal(const v1,v2,v3:TVector4f):TVector4f;
begin
 Result:=(v2-v1)*(v3-v1);
 Result.Normalize();
end;

Function GetNormal(const v1,v2,v3:TVector4f):TVector4f;
begin
 Result:=Normalize(Cross(Sub(v2,v1),Sub(v3,v1));
end;


 
oxffff ©   (2008-11-11 19:24) [18]


> @!!ex ©   (11.11.08 19:15) [17]


А что перегрузка операторов не работает?


 
oxffff ©   (2008-11-11 19:29) [19]


> jack128_   (11.11.08 18:32) [15]
>
> > Анонимный метод это интерфейс.
>
> Ха.  Блин, имхо - не правельно.  ТОчнее то что анонимные
> методы - как интефейсы реализованы - это понятно, но лично
> мне не ясно, нафиг эту внутреннюю кухню наружу выносить.
> .


Что неправильно? То что захват происходит при помощи программиста.
Можешь использовать способ. Он там тоже в комментах озвучен.

procedure MyDestroy(obj:Tobject);
asm
push eax;
mov eax,[eax+12];
call Tobject.Free;
//No necessity for finalization, just Freemem
//And there is no valid RTTI for finalization
pop eax;
call System.@Freemem;
end;

const DestroySlot:pointer=@MyDestroy;

procedure PatchVMT(obj:Tobject);
asm
mov [eax],offset DestroySlot+4;
end;

class function TSmartPointerFromRussia"T".Wrap2(const AValue: T): TFunc"T";
begin
PatchVMT(Tobject(dword(@AValue)-12));
Result := function: T
begin
Result := AValue;
end;
end;


 
oxffff ©   (2008-11-11 19:30) [20]


> Можешь использовать способ.


Мой способ. ;)


 
@!!ex ©   (2008-11-11 19:56) [21]

> [18] oxffff ©   (11.11.08 19:24)

Как раз работает.
Я просто объяснил, почему не хочется использовать фунации.
Операторы почти всегда нагляднее.
Почти - потому что если оператор переопределен не логично, это только запутывает код.


 
Slym ©   (2008-11-12 18:06) [22]

Опиши свои Variant типы (CustomVariant) получиш и астоубийство и создание и некоторые операции +-*/



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.12.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.036 c
15-1223891661
Правильный$Вася
2008-10-13 13:54
2008.12.21
как заставить VirtualDub понимать формат WMV


3-1211617055
Саша
2008-05-24 12:17
2008.12.21
Нужен пример запроса типа "рейтинг"...


15-1224537298
Германн
2008-10-21 01:14
2008.12.21
Поддержим отечественных производителей - 3


2-1225564992
codemaster
2008-11-01 21:43
2008.12.21
Перенос Item в TListBox


15-1224152807
stas
2008-10-16 14:26
2008.12.21
Вопрос по ASP.NET





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский