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

Вниз

Выбор из 2-х реализаций абстракции.   Найти похожие ветки 

 
dummy_user   (2012-12-08 18:34) [0]

Есть базовый абстрактный класс и 2 его реализации:


type
 TSuper = class
 private
   class function Init: boolean; virtual; abstract;
 public
   function  Load(const FileName: string): boolean; virtual; abstract;
 end;

 TSuper_Version_1 = class (TSuper);
 TSuper_Version_2 = class (TSuper);



И их использование:


var
 Super: TSuper;
begin
 TSuper.Init;                 // Тут вылетает.
 Super:= TSuper.Create;
end;


Как сделать директивный выбор между этими 2-мя реализациями?
Чтобы создавая Super: TSuper не заботиться о таком: Super: TSuper_Version_1?


 
dummy_user   (2012-12-08 18:35) [1]

Т.е. поставили директиву, что используем 1-ю реализацию, а потом
спокойно создаем Super: TSuper;


 
dummy_user   (2012-12-08 18:46) [2]

Почему выбирает 2-ю версию?


$DEFINE USE_VERSION_1}

function CreateSuper: TSuper;
begin
 {$IFDEF USE_VERSION_1}
 Result:= TSuper_Version_1.Create;
 {$ENDIF}
 Result:= TSuper_Version_2.Create;
end;

procedure Dummy;
var
 Super: TSuper;
begin
 Super:= CreateSuper;
 Windows.OutputDebugString(PAnsiChar(string(Super.ClassName)));
end;



 
TUser ©   (2012-12-08 18:52) [3]

Ты вызываешь абстрактный метод - конечно вылетает.


 
dummy_user   (2012-12-08 18:53) [4]


procedure Init;
begin
 {$IFDEF USE_VERSION_1}
 TSuper_Version_1.Init;
 {$ENDIF}
 TSuper_Version_2.Init;
end;



 
Германн ©   (2012-12-08 19:17) [5]


> Почему выбирает 2-ю версию?
>

Потому что нет {$ELSE}


 
знайка   (2012-12-08 19:57) [6]

А чего сделать то надо? :)


 
DVM ©   (2012-12-08 20:36) [7]


> dummy_user   (08.12.12 18:34) 

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


 
dummy_user   (2012-12-08 21:54) [8]

Как заменить это:

Super:= CreateSuper;

На это:

Super:= TSuper.Create;

Чтобы директивно все определялось.
Или как сделать перегрузку конструктора?


 
DVM ©   (2012-12-08 22:11) [9]


> dummy_user   (08.12.12 21:54) [8]


> Чтобы директивно все определялось.

{$IFDEF директива}
делаем одно
{$ELSE}
делаем другое
{$ENDIF}


 
dummy_user   (2012-12-09 00:37) [10]

Нет.
Я про это:


class function TSuper.CreateSuper: TSuper;
begin
 {$IF Defined(USE_VERSION_1)}
 Result:= TSuper_Version1.Create;
 {$ELSE}
 Result:= TSuper_Version2.Create;
 {$IFEND}
end;



Т.е. уже не могу создать просто сделав:
Super:= TSuper.Create;
Теперь так:
Super:= TSuper.CreateSuper;

Но мне кажется, так будет не правильно.
Нужно как-то в констукторе прописать какой класс создавать.


 
dummy_user   (2012-12-09 00:43) [11]

И еще, не знаю куда разместить инициализацию в классе TSuper.


function InitGlobal: boolean;
begin
 {$IF Defined(USE_VERSION_1)}
 Result:= TSuper_Version1.Init;
 {$ELSE}
 Result:= TSuper_Version2.Init;
 {$IFEND}
end;



Переопределить Init в TSuper?
Но этот код унаследуется и получится неправильно.

Сделать обычную процедуру как тут?
Но не хочется отделять логику TSuper-объектов в отдельные функции.

Создать TSuper.InitGlobal?
Выглядит как ерунда полнейшая.

Что делать, что выбрать?


 
silver ©   (2012-12-09 00:48) [12]

вопрос странный - делай, как удобно тебе
я директивами из платной бесплатную версию делаю, например



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

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

Наверх




Память: 0.49 MB
Время: 0.009 c
15-1353754852
dummy_user
2012-11-24 15:00
2013.03.31
Посоветуйте электронную читалку.


2-1348434236
ankazh
2012-09-24 01:03
2013.03.31
поиск в поле MEMO через SQL


15-1354371990
AlexKniga
2012-12-01 18:26
2013.03.31
Использование ICQ и права на текст сообщений


2-1348575201
ankazh
2012-09-25 16:13
2013.03.31
Раскладка клавиатуры


2-1348818757
ixen
2012-09-28 11:52
2013.03.31
Firebird и текстовое вычисляемое поле