Форум: "Основная";
Текущий архив: 2003.09.08;
Скачать: [xml.tar.bz2];
ВнизКласс-оболочка в каждой форме, исходный - один в главной Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.008 c