Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 17.07.2015, 14:23   #1
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
Стрелка Конструктор обобщённого типа.

Сабж возможен? Чот курил-курил маны, и не вкурил. Подскажите, кто постиг в сабже дзэн.
Дано:
Код:
function TAbstractOption.NewChildOption(const AKind: TOptionKind;
  const AName: string = ''): TXmlOption;
var
  E: EOptionSimple;
begin
  case AKind of
    okOrdinal: Result:= TXmlOptionOrdinal.Create(Self);
    okFloat:   Result:= TXmlOptionFloat.Create(Self);
    okPoint:   Result:= TXmlOptionPoint.Create(Self);
    okRect:    Result:= TXmlOptionRect.Create(Self);
    okString:  Result:= TXmlOptionString.Create(Self);

    okIntList: Result:= TXmlOptionIntList.Create(Self);

    // и так далее...
  else Result:= nil; // для вызова исключения
  end;

  if Assigned(Result)
    then begin
           if AName <> ''
             then Result.Name:= AName;

           Self.Add(Result);
         end
    else begin
           E:= EOptionSimple.CreateFmt('Запрещено созавать объекты "%s" внутри "%s".',
                                       [KindToStr(AKind), KindStr]);
           E.Sender:= Self;
           raise E;
         end;
end;
Здесь классы TXmlOptionХХХ - потомки класса TXmlOption. В зависимости от вида (параметр Kind) создаётся и возвращается экземпляр соответствующего класса.

Задача: заменить метод на что-то подобное:
Код:
function TAbstractOption.NewChildOption<T>(const AName: string [; другие нужные параметры]): T;
begin
  Result:= ....Create();
end;
Кто прочухал, подскажите-ка.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума
Старый 17.07.2015, 14:33   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А классику типа:
Код:
function TAbstractOption.NewChildOption(const AKind: TOptionKind;
  const AName: string = ''): TObject;
var
  E: EOptionSimple;
begin
  case AKind of
    okOrdinal: Result:= TXmlOptionOrdinal.Create(Self);
    okFloat:   Result:= TXmlOptionFloat.Create(Self);
    okPoint:   Result:= TXmlOptionPoint.Create(Self);
    okRect:    Result:= TXmlOptionRect.Create(Self);
    okString:  Result:= TXmlOptionString.Create(Self);

    okIntList: Result:= TXmlOptionIntList.Create(Self);
...
не желаешь?
I'm learning to live...
Stilet вне форума
Старый 17.07.2015, 14:37   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Заглянуть в код Application.CreateForm не?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума
Старый 17.07.2015, 14:40   #4
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
не желаешь?
Так оно уже есть (см. выше) и вполне себе работает. Просто перечисление TOptionKind со временем распухнет до over9000 значений, так что хотелось бы выкинуть case.

Цитата:
Заглянуть в код Application.CreateForm не?
Это метод-процедура, а мне нада функцию. И не спрашивать, почему!
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...

Последний раз редактировалось Poma][a; 18.07.2015 в 13:19.
min@y™ вне форума
Старый 17.07.2015, 14:58   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Дык переделай. Так примерно. Еще посмотреть какие подводные камни там

Код:
type
  TLabel1 = class(TLabel);
  TLabel2 = class(TLabel);
  TForm1 = class(TForm)
...

function CreateComponent(InstanceClass: TComponentClass; AOwner: TComponent): TComponent;
var Instance: TComponent;
    Reference: Pointer;
begin
  Instance:=TComponent(InstanceClass.NewInstance);
  TComponent(Reference):=Instance;
  try
    Instance.Create(AOwner);
  except
    TComponent(Reference):=nil;
  end;
  Result:=Reference;
end;

procedure TForm1.Button2Click(Sender: TObject);
var Label1: TLabel1;
begin
  Label1:=TLabel1(CreateComponent(TLabel1,Self));
  Label1.Top:=0;
  Label1.Left:=0;
  Label1.Caption:='ё-п-р-с-т';
  Label1.Parent:=Self;
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума
Старый 17.07.2015, 15:02   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Дык переделай.
Ща попробую. Вдруг получится?
Только обобщённых типов там не будет, а хотелось бы попутно в них разобраться.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума
Старый 17.07.2015, 15:23   #7
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Код:
type 
  TXMLOptionClass =class of TXMLOption;

function TAbstractOption.NewChildOption(const AKind: TXMLOptionClass;
  const AName: string = ''): TXmlOption;
begin
  result:=Akind.Create(self);
...
end;

xml1:=NewChildOption(TXMLOption1, ..);
.....
xml100:=NewCHildOption(TXMLOption100, ...);
программа — запись алгоритма на языке понятном транслятору
evg_m на форуме
Старый 17.07.2015, 15:53   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Сообщение от evg_m
Код:
type 
  TXMLOptionClass =class of TXMLOption;

function TAbstractOption.NewChildOption(const AKind: TXMLOptionClass;
  const AName: string = ''): TXmlOption;
begin
  result:=Akind.Create(self);
...
end;

xml1:=NewChildOption(TXMLOption1, ..);
.....
xml100:=NewCHildOption(TXMLOption100, ...);
Не прокатит, всё равно нужно явное приведение типа, а мне надо, чтобы функция возвращала сразу объект нужного класса, а не его класса-предка. Для это и хочу заюзать, если возможно, обобщённый тип.
Изображения
Тип файла: jpg 280523.jpg (54.6 Кб, 114 просмотров)
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума
Старый 17.07.2015, 16:10   #9
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

а если переделать с функции на процедуру с var парамером ?
так, как работает application.CreateForm
это предложение уже мелькало здесь.

Код:
procedure CreateXMLOption(var option: TXMLOption; optionClass: TXMLOptionClass);
begin
  result:=optionclass.Create();
  ...
end;

var
  option1: TXMLOption1;
  option100: TXMLOption100;

CreateXMLOption(option1, TXMLOption1);
option1.optionX;
CreateXMLOption(option100, TXMLOption100);
option100.optionY;
Цитата:
Это метод-процедура, а мне нада функцию. И не спрашивать, почему
ВСЕ ПОНЯЛ.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 17.07.2015 в 16:14.
evg_m на форуме
Старый 17.07.2015, 16:33   #10
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

А что-нибудь типа этого:
Код:
program project1;

{$mode objfpc}{$H+}
{$APPTYPE CONSOLE}


uses
  fgl;

type

  { TBaseOption }
  TBaseOption = class;
  TOneOption = class;
   TDuoOption = class;

  TBaseOption = class(TObject)
    private
      fName:string;
    public
      property Name:string read fName;
      constructor Create(const sName:string = 'BaseOption class instance'); overload;
      destructor Destroy; override;
  end;

 { TOneOption }

 TOneOption = class(TBaseOption)
 public
   constructor Create; overload;
   destructor Destroy; override;
 end;

 { TDuoOption }

 TDuoOption = class(TBaseOption)
 public
   constructor Create; overload;
   destructor Destroy; override;
 end;

 TOptions = specialize TFPGObjectList<TBaseOption>;

 //implementation

 { TBaseOption }

constructor TBaseOption.Create(const sName: string);
begin
  Inherited Create;
  fName := sName;
end;

destructor TBaseOption.Destroy;
begin
  inherited Destroy;
end;

{ TOneOption }

constructor TOneOption.Create;
begin
  Inherited Create('OneOption class instance');
end;

destructor TOneOption.Destroy;
begin
  inherited Destroy;
end;

{ TDuoOption }

constructor TDuoOption.Create;
begin
 Inherited Create('SecondOption class instance');
end;

destructor TDuoOption.Destroy;
begin
  inherited Destroy;
end;

var
  list:TOptions;
  one:TOneOption;
  duo:TDuoOption;
  base:TBaseOption;
  i:integer;
begin
  WriteLn('Hi');
  list := TOptions.Create();
  base:=TBaseOption.Create();
  one:=TOneOption.Create();
  duo:=TDuoOption.Create();
  try
    list.Add(base);
    list.Add(one);
    list.Add(duo);
    for i:=0 to list.Count -1 do
    begin
      WriteLn('Classes in list: '+list[i].Name);
    end;
  finally
     list.Free;
  end;
  ReadLn;
end.
итог:
Человек_Борща вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как сделать из числа типа real число типа integer? gylayko Помощь студентам 6 15.09.2012 11:41
Возможно ли в массив типа char записать первым элементом значение переменной типа float? Green Gin Общие вопросы C/C++ 2 05.12.2011 01:50
Каким образом сохранить цвет. Типа в переменную типа TColor ? serres C++ Builder 5 07.12.2010 16:19
С++ (конструктор, деструктор, копирующий конструктор) Jane-sad Помощь студентам 2 01.10.2010 10:01
Запись числа типа инт в ячейку двумерного массива типа char AxenicX Помощь студентам 1 25.09.2009 00:35