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

Вниз

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

 
MV   (2004-01-14 15:07) [0]

Господа, возможно, для Вас совершенно дурацкий вопрос:
- имеется класс, активно юзающий одно из своих свойств типа Record (какой-то структуры).
- все нормально, но нужен такой же класс, у которого это свойство типа Record bvttn совершенно другую структуру.
- дело решается позорным методом "copy-paste".
Понадобилось еще два класса. И возможно, потом еще два.
Теоретически возможно вместо Record использовать объекты, но, как выяснилось, фактически при активном создании-удалении элементов типа Record время тратится гораздо меньшее, чем при создании экземпляров класса.
Так вот вопрос: есть ли в Delphi какая-либо альтернатива шаблонов C++; или более локально - можно ли использовать структуры типа Record, если заранее не известно содержание Record. Внутри класса к полям записи не обращаюсь (только создание и удаление)

???????????????????????


 
Семен Сорокин   (2004-01-14 15:09) [1]

1. Variant parts in records
2. virtual class


 
MV   (2004-01-14 15:14) [2]

Не, variants parts не прокатит. Методы класса к внутренней структуре не обращаются, только экземпляры создаются.
Насчет Virtual class - что-то морщил-морщил сероватое вещество - никак не могу предстваить виртуальные типы свойств...


 
Романов Р.В.   (2004-01-14 15:18) [3]

Создаешь базовый клас в котором реализован общий код.
Создаешь потомков и добавляешь им разные проперти.


 
Семен Сорокин   (2004-01-14 15:19) [4]

насчет virtual class имел ввиду виртульный (возможно даже с абстрактными свойствами) класс, в зависимости от типа используемых данных. Реально же будет использоваться его оболочка. (по аналогии TStrings -> TStringList)


 
MV   (2004-01-14 15:22) [5]

2 Романов Р.В. © (14.01.04 15:18) [3]

Дык об чем и речь. У всех классов весь код совершенно одинаковый, акромя типов возращаемых функций и типов пропертей. Какой тут общий класс можно создать. Ну, поднапрячься можно, пару функций в родительский класс выделить, но проблемы не решить...

2 Семен Сорокин © (14.01.04 15:19) [4]
Абстрактные свойства в Delphi - это как?


 
Семен Сорокин   (2004-01-14 15:23) [6]

Абстрактные свойства в Delphi - это как?
методами (ошибся)


 
MV   (2004-01-14 15:35) [7]

Пример:
-------

type
TRec1 = Record
....
....
end;

type
TDynArray = class (TComponent) // Динамичесий массив с особым поведением
private
FGrid: TRec1;
function GetGrid(const Row, Col: integer): TRec1;
procedure SetGrid(const Row, Col: integer; const Value: TRec1);
public
property Grid[const Row,Col : integer] : TRec1 read GetGrid write SetGrid; default;
...
end;

------------------------
Ну так вот, если другая структура TRec1 - делай Copy/Paste.
Ну просто неприлично как-то, в 2004-то году...


 
Романов Р.В.   (2004-01-14 15:38) [8]

может подойдет F1 - Variant parts in records


 
yaJohn   (2004-01-14 15:39) [9]

Ochen" krivoe reshenie (esli vse klassi absolutno odinakovi) -
vinosim opredelenie klassa v otdelniy "MyClass.inc":
--------------
TMyClass = class
property MyProp: TMyProp ..........
end;
--------------

unit1.pas:
-----------------
type
TMyProp = record
x, y: integer;
end;

{$INCLUDE MyClass.inc}

TMyClass1 = class (TMyClass)
end;

.....................

end.
-----------------

unit2.pas:
-----------------
type
TMyProp = record
s: string;
a: array.....
end;

{$INCLUDE MyClass.inc}

TMyClass2 = class (TMyClass)
end;
..................
end.
-----------------

MainUnit.pas
-----------------
uses Unit1, unit2;

...........
var c1: TMyClass1;
c2: TMyClass2;
begin
c1.MyProp.x := 1;
c2.MyProp.s := "IZVRAT!!!";

--------

Nechto vrode shablonov klassov....... Da?


 
y-soft   (2004-01-14 15:42) [10]

А нельзя объявить в базовом классе свойство типа pointer и в потомках переопределять виртуальные методы доступа?

Можно также определить виртуальную функцию класса, возвращающую длину или код данных...


 
MV   (2004-01-14 15:43) [11]

2 yaJohn © (14.01.04 15:39) [9]

Ну, что {$INCLUDE MyClass.inc}, что copy/paste... Ваш код более компактен, конечно, но категорически несколько типов в одном модуле. Вообще, напоминает шаманство какое-то...

Все равно делфай не брошу!


 
MV   (2004-01-14 15:46) [12]

2 y-soft © (14.01.04 15:42) [10]

Да, что-то похожее я видел в исходниках компонента TVirtualTreeView... Они там вообще (в том числе и для скорости)свой менеджер памяти реализовали...
Вот беда-то... Не думал, что это ограничение Delphi так зацепит...


 
yaJohn   (2004-01-14 15:47) [13]

Shamanstvo, eto kogda vnutri podobnih konstrukciy est" rekursivnie $DEFINE & $IFDEF.


 
MV   (2004-01-14 15:49) [14]

2 yaJohn © (14.01.04 15:47) [13]
Спасибо, дяденька, не надо!


 
Семен Сорокин   (2004-01-14 15:54) [15]

type
t1 = record
q: string;
end;
p1 = ^t1;

t2 = record
e: double;
end;
p2 = ^t2;

tmyclass = class
private
FData: pointer;
end;

var
c1: tmyclass;
c2: tmyclass;

...
p1(c1.Fdata)^.q
p2(c1.Fdata)^.e


 
Семен Сорокин   (2004-01-14 15:57) [16]

это [15] если напрямую, но можно же и красивую оболчку (потомка) для базового класса сделать.
и непойму почему нельхя использовать Variant parts in records? там динамические массивы или строки есть?


 
MV   (2004-01-14 15:59) [17]

2 Семен Сорокин © (14.01.04 15:54) [15]

Это понятно.
Но как, используя нетипизированные указатели, создавать методами класса экземпляры записей конкретного типа?


 
Семен Сорокин   (2004-01-14 16:06) [18]

MV (14.01.04 15:59) [17]
type
_t1= record
s: string;
end;
_p1= ^_t1;
var
_p: pointer;
...
New(_p);
_p1(_p)^.s := "bla-bla-bla";

если я правильно понял вопрос


 
Verg   (2004-01-14 16:11) [19]


> Насчет Virtual class - что-то морщил-морщил сероватое вещество
> - никак не могу предстваить виртуальные типы свойств...


Это можно понимать так, как класс с виртуальным конструктором (чего, кстати в С++ нет).
Т.е. все твои record-ы (Trecx) делаются классами с одним общим предком и имеющими соотв. виртуальный конструктор. Поле "несущего" класса (FRecx) именно того базового виртуального (TBaseClass) предка предка. В конструкор TDynArray передается уже конкретный КЛАСС потомка TBaseClass.
...
FGrid : TBaseClass;
...
constructor TDynArray.Create( MemberClass : class of TBaseClass);
begin
FGrid := MemberClass.Create(....);
end;
...со всеми вытекающими, как говориться...

TNewRec = class(TBaseClass)
constructor Create(.....); override;
end;
.....
begin
NewDynaArray := TDynaArray(TNewRec);
....

Понятно?


 
MV   (2004-01-14 16:17) [20]

2 Verg © (14.01.04 16:11) [19]

С класса вместо Record сделано было в первую очередь. Все работало. Но при активном создании/удалении очень большого числа экземпляров класса - ОЧЕНЬ МЕДЛЕННО.
C Record - очень быстро.


 
MV   (2004-01-14 16:29) [21]

Ну, можно использовать нетипизированные указатели...
А в конструктор передавать тип записи как дополнительный параметр, и вычислять (для будушего распределения памяти) ее размер. А после, вместо New юзать GetMem
Как-то все это криво....


 
Verg   (2004-01-14 16:32) [22]

Быстро- медленно. Я не об этом, я про что понималось под "виртуальным классом"


> Но как, используя нетипизированные указатели, создавать
> методами класса экземпляры записей конкретного типа?


В конструктор передавать размер конкретной единичной записи (размер элемента массива).

А при выборке(записи) экземпляров - typecasting-ом.

Ты же все равно в каком-то контексте должен точно знать с экземпляром какого типа ты будешь иметь дело. Другое дело, что компиллер не имеет возможность проконтролировать корректность приведения типа.

В чистом виде class template-ов в делфи нет.
А неудобство это вызывает чисто непривычка.


 
Семен Сорокин   (2004-01-14 16:33) [23]

Как-то все это криво....
имхо, не кривее нескольких типов в одном модуле :)
а вообще конечно проще с классами.
очень большого числа экземпляров класса
это сколько? может стоит вынести в поток.


 
MV   (2004-01-14 16:38) [24]

А неудобство это вызывает чисто непривычка.
Да вот как-то не было надобности раньше...

имхо, не кривее нескольких типов в одном модуле :)
Да не обязательно в одном - скорее, наоборот... Хотя тут один чел предложил - если в разных модулях - то общий код в include - файл вынести... Шаманство какое-то...


 
y-soft   (2004-01-14 17:05) [25]

>MV

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

А насчет кривизны хранения данных как pointer и отдельно длины или идентификатора типа, так IMHO не так уж это и криво...


 
MV   (2004-01-14 17:13) [26]

2 y-soft © (14.01.04 17:05) [25]

Так и буду делать, похоже...
В конструктор класса - менеджера буду передавать тип записи, пусть вычисляет и запоминает размер, а дальше по GetMem/FreeMem рулит... Ох.


 
panov   (2004-01-14 17:21) [27]


type

TProcRecCreate = function: Pointer;

TMyClass=class(TObject)
FPRec: Pointer;
FProcRecCreate: function:pointer;
public
constructor Create(aProc: TProcRecCreate);
end;

function CreateRec1: Pointer;
var
FClass: TMyClass;

implementation

function CreateRec1: Pointer;
type
PRecType=^RecType;
RecType=record
FInt: Integer;
FStr: String;
end;
var
pRec : PRecType;
begin
New(pRec);
Result := pRec;
end;

constructor TMyClass.Create(aProc: TProcRecCreate);
begin
inherited Create;
FProcRecCreate := aProc;
FPRec := FProcRecCreate;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
FClass := TMyClass.Create(CreateRec1);
end;



 
panov   (2004-01-14 17:24) [28]

Достаточно в public добавить еще функцию SetProcCreateRec для переопределения функции создания структуры, и можно в одном экземпляре класса создавать разные структуры...


 
MV   (2004-01-14 17:38) [29]

2 panov © (14.01.04 17:24) [28]

Ну, опять-таки, при переопределении функции типы параметров и возвращаемых значений менять нельзя вроде...


 
Verg   (2004-01-14 17:43) [30]

You can declare more than one routine in the same scope with the same name. This is called overloading. Overloaded routines must be declared with the overload directive and must have distinguishing parameter lists. For example, consider the declarations

function Divide(X, Y: Real): Real; overload;

begin
Result := X/Y;
end;

function Divide(X, Y: Integer): Integer; overload;

begin
Result := X div Y;
end;

These declarations create two functions, both called Divide, that take parameters of different types. When you call Divide, the compiler determines which function to invoke by looking at the actual parameters passed in the call. For example, Divide(6.0, 3.0) calls the first Divide function, because its arguments are real-valued.

(С) Delphi Help


 
MV   (2004-01-14 17:45) [31]

2 Verg © (14.01.04 17:43) [30]

Ну я ж и говорю - copy/paste...


 
Семен Сорокин   (2004-01-14 17:46) [32]

MV (14.01.04 17:38) [29]
Ну, опять-таки, при переопределении функции типы параметров и возвращаемых значений менять нельзя вроде...

это, как говориться: "и на ёлку залезть и ж..у не ободрать" :))
да только приведением.


 
MV   (2004-01-14 17:52) [33]

Пойду-ка я домой. Буду отдыхать лежа (спать) и думать о судьбе Отечества. Всем большущее спасибо.



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

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

Наверх





Память: 0.53 MB
Время: 0.006 c
1-83175
New
2004-01-15 15:04
2004.01.26
OpenDialog


1-83152
Kremen
2004-01-15 11:49
2004.01.26
Програмное переключение языка


1-83158
pserg
2004-01-14 23:58
2004.01.26
Поиск фрагмента текста в файлах MSWord


6-83227
MAXIMUS 2003
2003-11-20 12:32
2004.01.26
Подключение по сети к папке


6-83223
Raptorus
2003-11-20 16:33
2004.01.26
Естьли достойный конкурент Indy-компонентам для работы с сокетами





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский