Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.08;
Скачать: CL | DM;

Вниз

Класс-оболочка в каждой форме, исходный - один в главной   Найти похожие ветки 

 
Dm1625   (2003-08-25 13:18) [0]

не могу сообразить как это написать правильно

в главной форме проекта создается класс - один экземпляр
все формы проекта вызывают функции этого экземпляра

надо: обернуть этот класс, чтобы формы вызывали функции класса-оболочки (один экземпляр класса-оболочки в каждой форме), ну а функции класса-оболочки будут добавлять идентификатор формы и вызывать уже настоящую функцию

что-то вроде
TClass = class
function F1(FormID: longint)
end;

TClassWrapper = class
function F1 () - вызывает function F1(FormID: longint)
и подставляет идентификатор формы, который получает при создании
end;

FrmMain
Class1: TClass;
end;

FrmAny
ClassWrapper1: TClassWrapper;

и надо правильно конструкторы оформить


 
unreger   (2003-08-25 13:39) [1]

Это я был

Поясню: класс работает с данными, один экземпляр
чтобы все формы обмениваются данными с сервером через него (меняются только параметры и хранимые процедуры, механизм один),
чтобы не писать обработчик ошибок в каждой форме, поместим обработчик в класс. Но надо знать какая форма вызвала функцию. Эту задачу выполняет класс-оболочка, экземпляр которого есть в каждой форме.


 
Skier ©   (2003-08-25 13:42) [2]

Если я правильно понял то видимо так :

TClass = class
function F1(FormID: longint); virtual;
end;

TClassWrapper = class
function F1(FormID: longint); override;
end;

Нет ?


 
Palladin ©   (2003-08-25 13:42) [3]

TClass = class
function F1(FormID: longint); virtual;
end;

TClassWrapper = class (TClass)
function F1; override;
end;

function TClassWrapper.F1;
begin
inherited (1);
end;


 
unreger   (2003-08-25 13:48) [4]

э-э-э...

По моему не так.

TClass совершенно реальный, создается один экземпляр этого класса, в нем код, который выполняется

TClassWrapper просто вызывает функцию из экземпляра TClass (но экземпляр TClassWrapper в каждой форме)

примерно так

TClassWrapper.F1()
begin
TClass.F1(FormID); FormID получен при создании TClassWrapper
end;

Я вызываю F1(), а оболочка подставляет параметры и вызывает дальше.


 
Palladin ©   (2003-08-25 13:51) [5]

Экземпляр класса называется объект, в вопросе шла именно речь о наследовании классов.


 
Skier ©   (2003-08-25 13:53) [6]

Поправлюсь : TClassWrapper = class(TClass) конечно же...


 
Palladin ©   (2003-08-25 13:53) [7]

И что значит фраза "TClass совершенно реальный"? Skier и я что то не реальное привели чтоли?


 
Skier ©   (2003-08-25 13:55) [8]

Да и хорошо бы класс не называть TClass, такой в Delphi уже имеется...


 
unreger   (2003-08-25 14:11) [9]

>Экземпляр класса называется объект, в вопросе шла именно речь о наследовании классов.

согласен, с терминологией я был неправ.
Попробуем еще раз:

В главной форме проекта создается экземпляр класса.
CData: TCData;
Этот экземпляр единственный для всего проекта.

В каждой форме создается экземпляр класса-оболочки.
CDataWrapper: TCDataWrapper;

CDataWrapper при создании получает (как?) ссылку на CData и идентификатор формы, в которой создается.

Набор функций CDataWrapper полностью дублирует CData, но
с уменьшеным количество параметров

CDataWrapper.F1()
begin
// вот тут надо решить через указатель на CData
CData.F1(FormID); FormID получен при создании CDataWrapper
end;


 
unreger   (2003-08-25 14:14) [10]

>И что значит фраза "TClass совершенно реальный"?
имелось ввиду "не содержит виртуальных функций"


 
Skier ©   (2003-08-25 14:15) [11]


> Набор функций CDataWrapper полностью дублирует CData, но
> с уменьшеным количество параметров

справук по overload посмотри, кроме того могут помочь
дефолтные параметры.


 
unreger   (2003-08-25 14:23) [12]

почему overload?
мне важно выполнять код из экземпляра CData, не перекрывая, т.е.

CDataWrapper.F1()
begin
inherited F1(FormID);
end;

пожалуй не пойдет

я представляю что-то вроде
constructor TCDataWrapper.Create(GeneralData: ^TCData) - что-то вроде этого
и определяем класс формы, в котором создали CDataWrapper


 
Palladin ©   (2003-08-25 14:26) [13]

хм, все это мне напоминает паттерны mediator и command...
почитай на rsdn статью в разделе "паттерны проектирования" там про это рассказано, и не только про это. Причем построено реальное приложение.


 
Camus ©   (2003-08-25 14:27) [14]

А зачем вообще какие-то оболочки?

type
TCData = class(...)
...
procedure MyProc(Form: TForm; ...);
end;

TForm1 = class(TForm)
...
private
FCData: TCData;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property CData: TCData read FCData;
end;

constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
FCData := TCData.Create(...)
end;

destructor TForm1.Destroy;
begin
FCData.Free;
inherited
end;

И все. Вызов из любой формы, например, такой:
Form1.CData.MyProc(Self, ...);
(естественно, модуль с TForm1 надо включить в uses).


 
Skier ©   (2003-08-25 14:27) [15]


> CDataWrapper.F1()
> begin
> inherited F1(FormID);
> end;
>
> пожалуй не пойдет

Почему ? Доводы...


 
unreger   (2003-08-25 14:28) [16]

обязательно, но с указателями помоги сейчас?
А я дальше расскажу интересную идею.


 
Palladin ©   (2003-08-25 14:29) [17]

а указатель тебе зачем? прямо так передавай.


 
unreger   (2003-08-25 14:29) [18]

>Form1.CData.MyProc(Self, ...);
Вот это-то и не хочется. За счет оболочки будет так:
Form1.CData.MyProc(...);


 
unreger   (2003-08-25 14:32) [19]

>а указатель тебе зачем? прямо так передавай.

и что будет? В смысле - останется ли один экземпляр CData? Или будет создан еще один внутри экземпляра CDataWrapper ?


 
Skier ©   (2003-08-25 14:33) [20]


> Или будет создан еще один внутри экземпляра CDataWrapper
> ?

А почему он должен создаваться ?!
Ты всех уже запутал ! :)
Давай выкладывай проблему целиком !


 
Camus ©   (2003-08-25 14:36) [21]

> unreger (25.08.03 14:29) [18]
> Вот это-то и не хочется. За счет оболочки будет так:
> Form1.CData.MyProc(...);

То есть, ТОЛЬКО ради того, чтобы не передавать один параметр, плодим кучу дополнительных объектов?
Смысл?


 
unreger   (2003-08-25 14:37) [22]

проблема у меня :)
с указателями.

constructor TCDataWrapper.Create(GeneralData: TCData)

Вот мне кажется, что будет создан экземпляр класса TCData, хотя, если подумать, то с чего бы ему создаваться.
GeneralData: TCData - это же указатель, и передается тоже указатель на уже существующий экземпляр, правильно?


 
default ©   (2003-08-25 14:38) [23]

unreger (25.08.03 14:37) [22]
на копию


 
Skier ©   (2003-08-25 14:38) [24]


> Вот мне кажется, что будет создан экземпляр класса TCData

Не будет.

> GeneralData: TCData - это же указатель, и передается тоже
> указатель на уже существующий экземпляр, правильно?

Правильно.

Ещё что нужно развеять ? :)


 
unreger   (2003-08-25 14:39) [25]

То есть, ТОЛЬКО ради того, чтобы не передавать один параметр, плодим кучу дополнительных объектов?

А они маааленькие...

Указатель очень часть придется передавать. Буквально в каждой функции проекта.


 
Skier ©   (2003-08-25 14:39) [26]

>default © (25.08.03 14:38) [23]
???!!!


 
unreger   (2003-08-25 14:40) [27]

default
на копию

Skier
> указатель на уже существующий экземпляр, правильно?
Правильно

Вы уж определитесь


 
Camus ©   (2003-08-25 14:40) [28]

> Вот мне кажется, что будет создан экземпляр класса TCData?

С какой стати? Передается ссылка (адрес), вот и все. А уж на что там она указывает, верно или неверно, существует по этому адресу объект или не существует - за это отвечает программист.


 
Skier ©   (2003-08-25 14:42) [29]

>unreger (25.08.03 14:40) [27]


> Вы уж определитесь

А что тут определяться !
Не слушай default и жизнь наладится.


 
default ©   (2003-08-25 14:42) [30]

Skier © (25.08.03 14:39) [26]
да, указатель на оригинал по-моему(основываясь на практике)
значит если var ставить ничего не изменится..
щас влом в CPU смотреть


 
Camus ©   (2003-08-25 14:43) [31]

Передается действительно копия (нет var), но копия не объекта, а его адреса. Указывает же она на все тот же объект.


 
Skier ©   (2003-08-25 14:46) [32]

>default © (25.08.03 14:42) [30]
Не надо про var !
Копируется только указатель, а не объект.
Автора интересует объект !


 
default ©   (2003-08-25 14:47) [33]

Camus © (25.08.03 14:43) [31]
ещё бы передавался указатель на указатель была бы вообще сказка...
unreger
оригинал оригинал(просто var компилятор не даёт "ставить")


 
unreger   (2003-08-25 14:48) [34]

Ну и ладно, но не поверите, тупо сидел с этой проблемой ... очень долго.

Слушайте дальше, зачем все это.

В проекте используются только функции из CData, других мало и не важны. В CData создается СОЕДИНЕНИЕ с сервером. Для контроля и различения пользователей особо требуем именно одно соединение.

Когда связь пропадет, или на сервере проверка данных не пройдет, возникнет ошибка. Чтобы не оборачивать каждый вызов функции в try-except, я все обработчики помещаю в CData. Вот зачем при вызове функции надо знать из какой формы он пришел.

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


 
default ©   (2003-08-25 14:50) [35]

вообще изначально вопрос про указатель был туп поскольку
переменная типа объекта это указатель, а они всегда передаются "как есть"
P.S. просто я малость не выспался...


 
unreger   (2003-08-25 14:51) [36]

Ну сбивает меня отсутсвие необходимости явно обозначать указатель


 
Skier ©   (2003-08-25 14:54) [37]

Ну и ?
Чем наследование не устраивает ? Не понимаю...


 
default ©   (2003-08-25 14:55) [38]

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


 
unreger   (2003-08-25 14:57) [39]

>Чем наследование не устраивает ? Не понимаю...

Да пожалуй, что и устраивает. Как всегда, пока формулируешь - половину ответа получаешь. Спасибо. Эх бежать надо, но завтра загляну


 
unreger   (2003-08-26 06:25) [40]

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

Тогда можно, конечно, в CDataWrapper хранить ссылку на это поле, вернее ссылку на объект, туда же, куда ссылается поле базового класса CData. Но это не правильно, поскольку значение поля часто меняется (объект пересоздается) и остлеживать вручную все ссылки...

Получается, мне надо работать именно с экземпляром базового класса, т.е.
constructor TCDataWrapper.Create(GeneralData: TCData)

а к методам будем обращаться так:

function TCDataWrapper.F1(): longint;
begin
F1:=GeneralData.F1(FormID);
end;

Правильно?



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

Текущий архив: 2003.09.08;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.026 c
6-24571
venoel
2003-07-06 21:41
2003.09.08
Формирование картинки на сервере


6-24597
RedFox
2003-07-02 12:12
2003.09.08
Поддержка сети в Delphi 7


1-24442
Nikolai_S
2003-08-25 10:24
2003.09.08
Работа с MS Word через TWordApplication


3-24347
Марат
2003-08-18 06:37
2003.09.08
F1Book


6-24575
zep
2003-07-06 12:51
2003.09.08
Разрыв Dial-Up соединения