powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Можно ли восстановить тип по объявленной переменной?
32 сообщений из 32, показаны все 2 страниц
Можно ли восстановить тип по объявленной переменной?
    #39545434
SergeyOren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемые форумчане!

Подскажите самоучке:
Есть несколько экземпляров разных потомков одного класса. Они объявлены в соответствии со своим классом с перекрытием Create-а, но не инициализированы.
Хотелось бы для экономии памяти инициализировать их по необходимости в процедуре, переменной в которой выступает экземпляр. Например:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type MainClass = class
...........
end;

type Class1 = class(MainClass)
.............
end;

type Class2 = class(MainClass)
.............
end;
//=======================
var Sample1 : Class1;
Sample2 : Class2;
//========================
procedure InitSample(var Sample;........)
begin
 //Вот тут хочется узнать тип Sample (Class1 или Class2) и при необходимости выполнить соответствующий Create.
end;


Благодарен за любую помощь

Модератор: Пользуйтесь тегом (кнопкой) SRC для оформления кода, пожалуйста.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545454
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergeyOren,

Ну, например так:

Код: pascal
1.
2.
3.
4.
5.
6.
procedure InitSample(Sample: TObject)
begin
  if Sample is Class1 then ... // Sample - это Class1 *или его наследник*
  // вариант 2:
  if Sample.ClassName = 'Class1' then ... // Sample - это Class1
end;
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545521
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНу, например так:Sample = nil
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545524
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergeyOren,

В такой постановке задача не решается. Для инициализации нужна еще информация о типе
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545545
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_В такой постановке задача не решается
Да ладно...
Код: pascal
1.
2.
3.
4.
5.
If @Sample = @Sample1 Then
 Sample := Class1.Create
Else
 If @Sample = @Sample2 Then
  Sample := Class2.Create;


Только, фу так делать.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545556
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergeyOren,

задание типа через "class of" нет?
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545560
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
type MainClass = class
public
  constructor Create; virtual;
end;

TMainClassClass = class of MainClass;

type Class1 = class(MainClass)
public
  constructor Create; override;
end;

type Class2 = class(MainClass)
public
  constructor Create; override;
end;
//=======================
var Sample1 : Class1;
Sample2 : Class2;
//========================
procedure InitSample(var Sample; AClass: TMainClassClass);
begin
  MainClass(Sample) := AClass.Create;
end;

InitSample(Sample1, Class1);
InitSample(Sample2, Class2);
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545562
Freedoom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey_Vasilisk_В такой постановке задача не решается
Да ладно...
...
Только, фу так делать.
И не надо так делать . Что мешает сделать по образу и подобию работы с формами:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
type
  TClassMainClass = cass of MaintClass;

procedure InitSample(var aSample: MainClass; aClass: TClassMainClass);
begin
  aSample := aClass.Create(...)
end;
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545563
Freedoom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пока писал ответ, уже накидали
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545566
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FreedoomЧто мешает сделать по образу и подобию работы с формами
Ничто не мешает, но условия определяю не я.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545572
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня один вопрос остался: где тут

SergeyOrenХотелось бы для экономии памяти
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545573
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Sample = nil
Да, что-то я затупил. Тогда действительно, не решается.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545576
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpТогда действительно, не решается.
Прекращай тупить
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545589
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey Прекращай тупить Kazantsev Alexeyфу так делать.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545607
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Но задача, тем не менее, решается.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545650
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyalekcvpТогда действительно, не решается.
Прекращай тупить
Ага, а если эта переменная в другом классе (и юните) объявлена как private? :)
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545656
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Spring 4D + Lazy инициализация
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545657
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpАга, а если эта переменная в другом классе (и юните) объявлена как private? :)
А если не ударяться в фантазии?
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545747
SergeyOren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Огромное спасибо за заботу, пойду дерзать...
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39545885
SergeyOren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker,

спасибо, но при таких вызовах InitSample я вынужден руками указывать тип, чего как раз хотелось избежать.
Да и стоит ли городить, когда можно вместо InitSample просто вызвать Create из типа, который я все равно должен указать в InitSample.
Но все равно спасибо
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546215
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если конструктор без параметров и переопределен через override то делается через
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
procedure TForm7.Test<T>(var aSample);
var
  Rc: TRttiContext;
  Rt: TRttiType;
  Rm: TRttiMethod;
begin
  Rc := TRttiContext.Create();
  try
    Rt := Rc.GetType(TypeInfo(T));
    // T(aSample) := Rt.AsInstance.MetaclassType.Create() as T; можно так или как ниже
    for Rm in Rt.GetMethods() do
      if Rm.IsConstructor and (Length(Rm.GetParameters()) = 0) then
      begin
        T(aSample) := Rm.Invoke(Rt.AsInstance.MetaclassType, []).AsType<T>();
        Break;
      end;
  finally
    Rc.Free();
  end;
end;
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546341
Фотография Virtual Student
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteЕсли конструктор без параметров и переопределен через override то делается через
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
procedure TForm7.Test<T>(var aSample);
var
  Rc: TRttiContext;
  Rt: TRttiType;
  Rm: TRttiMethod;
begin
  Rc := TRttiContext.Create();
  try
    Rt := Rc.GetType(TypeInfo(T));
    // T(aSample) := Rt.AsInstance.MetaclassType.Create() as T; можно так или как ниже
    for Rm in Rt.GetMethods() do
      if Rm.IsConstructor and (Length(Rm.GetParameters()) = 0) then
      begin
        T(aSample) := Rm.Invoke(Rt.AsInstance.MetaclassType, []).AsType<T>();
        Break;
      end;
  finally
    Rc.Free();
  end;
end;


+1
Красиво!
Ну, а дальнейшее, я думаю, автор темы распространит по количеству параметров.
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546412
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Virtual StudentНу, а дальнейшее, я думаю, автор темы распространит по количеству параметров.
Если кол-во параметров заранее неизвестно в конструкторе, то делается лямбда которая вызывается в момент выполнения конструктора с передачей соответствующзего объекта у которого уже будет нужный метод для инициализации
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546415
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть же TValue
Что вы гоните :)
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546506
SergeyOren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
X-Cite,
спасибо. Я подозревал, что задача решается ч/з RTTI, но подойти на практике образования не хватает.
Где можно почитать, чтобы осознанно модифицировать ваш код (у меня Create-ы сложные с разным набором пар-ов)?
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546555
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergeyOrenЯ подозревал, что задача решается ч/з RTTI,Какой RTTI, если Вам нужно явно указать нужный тип?
X-Cite
Код: pascal
1.
procedure TForm7.Test<T>(var aSample);
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546687
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Какой RTTI, если Вам нужно явно указать нужный тип?
Вся соль в том, что он знает какой тип будет...
Согласно его постановке у него есть
Код: pascal
1.
2.
3.
var
  Sample1 : Class1;
  Sample2 : Class2;


И где то он будет вызывать
Код: pascal
1.
InitSample(Sample1)


т.е. в этом месте в коде он уже знает что передает переменную Class1. Т.е. что мешает вызывать
Код: pascal
1.
InitSample<Class1>(Sample1, делегат на конструктор);
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546768
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteТ.е. что мешает вызывать
Код: pascal
1.
InitSample<Class1>(Sample1, делегат на конструктор);

Что мешает вызвать
Код: pascal
1.
Sample := Class1.Create(...)

?
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39546782
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite
Код: pascal
1.
procedure TForm7.Test<T>(var aSample);

И, кстати, при наличии виртуального конструктора есть более простой способ

Код: pascal
1.
2.
3.
4.
5.
6.
function TForm7.Init<T: TMainClass>(var ASample: T): T;
begin
  if ASample = nil then
    ASample := T(TMainClassClass(T).Create(...));
  Result := ASample;
end;

но это, опять таки, требует явного указания типа
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39547274
SergeyOren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Что мешает вызвать
Sample := Class1.Create(...)?

Сейчас так и вызываю, просто классов около 2-х
десятков, они описывают устройства в эксп. установке. Установка решает разные задачи (иногда одновременно), устройства нужны не во всех задачах и даже не на всех этапах одной задачи. Для экономии по возможности я деинициализирую отработавшие в задаче устройства. Беда в том, что господа Пользователи регулярно заставляют меня программировать новые задачи и я просто устал следить за состоянием устройств. Вот и подумал, что если тип устройства уже объявлен, то у компилятора д.б. способ подставлять его в нужном месте. Судя по развитию темы, это слишком оптимистично
...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39547525
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergeyOren,

Может Вам нужна такая схема?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
TMyClass = class
private
  FSample1: TSample1;
  FSample2: TSample2;
  ........
  FSampleN: TSampleN;
private
  function GetSample1: TSample1;
  function GetSample2: TSample2;
  ........
  function GetSampleN: TSampleN;
public
  destructor Destroy; override;
public
  property Sample1: TSample1 read GetSample1;
  property Sample2: TSample2 read GetSampleN;
  ........
  property SampleN: TSampleN read GetSampleN;
end;

function TMyClass.GetSample1: TSample1;
begin
  if FSample1 = nil then
    FSample1 := TSample1.Create(.......);
  Result := FSample1;
end;

function TMyClass.GetSample2: TSample2;
begin
  if FSample2 = nil then
    FSample2 := TSample2.Create(.......);
  Result := FSample2;
end;
......................
function TMyClass.GetSampleN: TSample1;
begin
  if FSampleN = nil then
    FSampleN := TSampleN.Create(.......);
  Result := FSampleN;
end;

destructor TMyClass.Destroy; override;
begin
  FSample1.Free;
  FSample2.Free;
  .............
  FSampleN.Free;
  inherited Destroy;
end;

var
  MyObj: TMyClass;
begin
  MyObj := TMyClass.Create(....);
  try
    MyObj.Sample3.DoSomething;
  finally
    MyObj.Free;
  end;
end;

...
Рейтинг: 0 / 0
Можно ли восстановить тип по объявленной переменной?
    #39547565
SergeyOren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Может Вам нужна такая схема?

Большое спасибо, буду завтра разбираться, т.к. у нас уже поздно - пора в стойло.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Можно ли восстановить тип по объявленной переменной?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]