powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как создать копию(клон) объекта ?
18 сообщений из 18, страница 1 из 1
Как создать копию(клон) объекта ?
    #39794098
Maxim.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос к делфистам.

Заранее(до запуска) не известен тип класса(знаем только родителя). А в режиме RunTime выясняется тип класса(у объекта) и нужно создать копию объекта.
Вот начало кода, помогите дописать ...

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

var 
  l_Src: tMyObject; 
  l_Dst: TObject;   

begin
   l_Src := tMyObject.Create;
   l_Dst := MakeClone(l_Src);  //  должна вернуть новый объект tMyObject
   // ...
end;

function MakeClone(aSrc: TObject): TObject;
begin
   // плиз, помогите дописать этот метод
   Result := (здесь д.б. реальный тип объекта aSrc).Create;
end;


Спасибо.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794103
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim.Kздесь д.б. реальный тип объекта aSrc

У TObject не так уж и много методов и свойств. Даже полный лентяй способен прочитать
описание каждого, включая ClassType.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794106
Maxim.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry SibiryakovДаже полный лентяй способен прочитать описание каждого, включая ClassType.

Спасибо за ответ.
Но, к сожалению ClassType никак не подходит для режима RunTime , т.к. его действие фиксируется на этапе компиляции.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794116
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim.KDimitry SibiryakovДаже полный лентяй способен прочитать описание каждого, включая ClassType.

Спасибо за ответ.
Но, к сожалению ClassType никак не подходит для режима RunTime , т.к. его действие фиксируется на этапе компиляции.

Sure?
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794125
loww
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: 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.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Classes;

type
  TMyClass = class of TMyObject;
  TMyObject = class (TPersistent)
    constructor Create; virtual;
    function AsStr: string; virtual;
  end;

  TMyObject1 = class (TMyObject)
    constructor Create; override;
    procedure Assign(Source: TPersistent); override;
    function AsStr: string; override;
  end;

  TMyObject2 = class (TMyObject)
    constructor Create; override;
    procedure Assign(Source: TPersistent); override;
    function AsStr: string; override;
  end;

constructor TMyObject.Create;
begin
end;

function TMyObject.AsStr: string;
begin
  Result := 'TMyObject';
end;

constructor TMyObject1.Create;
begin
  inherited Create;
end;

procedure TMyObject1.Assign(Source: TPersistent);
begin
  if Source is TMyObject1 then ;
end;

function TMyObject1.AsStr: string;
begin
  Result := 'TMyObject1';
end;

constructor TMyObject2.Create;
begin
  inherited Create;
end;

procedure TMyObject2.Assign(Source: TPersistent);
begin
  if Source is TMyObject2 then ;
end;

function TMyObject2.AsStr: string;
begin
  Result := 'TMyObject2';
end;

var
  M: TMyObject1;
  Clone: TMyObject;
begin
  try
    M := TMyObject1.Create;

    Clone := TMyClass(M.ClassType).Create;
    Clone.Assign(M);

    WriteLn(M.AsStr);
    WriteLn(Clone.AsStr);
    ReadLn;

    Clone.Free;
    M.Free;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794160
Maxim.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
loww
Код: pascal
1.
2.
3.
4.
  TMyObject = class (TPersistent)
  ...
  Clone := TMyClass(M.ClassType).Create;
  ...  


loww ,
большое спасибо за наводку, благодаря Вам найдено решение.
Нужно наследоваться от класса скомпилированного с RTTI: это либо наследники TPersistent, либо любой класс с директивой компилятора {$M+}. И эти классы должны иметь виртуальные конструкторы .
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794173
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это если Assign реализован.
В 99.00% реализации Assign НЕ происходит копирование PRIVATE свойств
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794284
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,

значит в понятие "копия объекта" эти свойства не входят

аналог из реального мира, если мне нужна копия яблока - мне нужно чтобы была та же форма, цвет, вкус, вес...
но мне вовсе не нужно, чтобы обе копия яблока занимали одно и то же место в пространстве. Свойства X,Y,Z в данном случае в понятия "копия" не входят

Скорее всего, копироваться должны только те свойства, которые входят в вычисление хэша объекта.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794318
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochаналог из реального мира, если мне нужна копия яблока - мне нужно чтобы была та же форма, цвет, вкус, вес...
Копия яблока не подразумевает копию ходов прогрызенных червяками и самих червяков.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794327
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim.KКак создать копию(клон) объекта ?

В общем виде - никак. Более того, есть классы, специально обученные противодействовать такому.
И даже простая попытка создания именованного компонента, лежащего на форме, может вызвать исключение "компонент с таким именем уже есть".

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

Например, ты можешь все "клонируемые" классы обучить клонироваться (что бы ты под этим не подразумевал), и просто вызывать нужный метод...
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794334
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr, вроде Assign тут ни при чем, зачем о нем говорят?
Как я понял, автор хочет создать объект того же самого класса. А копировать содержимое можно любым способом и без Assign.
Так?
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794335
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st...А копировать содержимое можно любым способом...

Конечно, можно. Если такой способ существует. А если не существует - то нельзя.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794492
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBrAriochаналог из реального мира, если мне нужна копия яблока - мне нужно чтобы была та же форма, цвет, вкус, вес...
Копия яблока не подразумевает копию ходов прогрызенных червяками и самих червяков.

отлично! В таком случае червяки и их норы будут отсутствовать в .Assign и в .GetHashCode
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794775
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно тупо скопировать занимаемый объектом участок памяти. Но это грязно и чревато
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794825
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Суть класса в том, что он закрытый к изменению извне. И что у него внутри никому не известно. Поэтому только он сам себя имет право копировать. Обычно для этого вводится интерфейс по типу IClonable с единственным методом Clone. И все ваши классы которые должны уметь копироваться просто его реализуют. Проблема в том что по умолчанию в delphi интерфейсы не облегченные. И поэтому всем таким классам надо писать заглушки или унаследоваться от TSingletonImplementation.
Если вы хотите клонировать чужие классы, то или чтото не так в вашей архитектуре или надо в них влезать.
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39794990
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteСуть класса в том, что он закрытый к изменению извне. И что у него внутри никому не известно. Поэтому только он сам себя имет право копировать. Обычно для этого вводится интерфейс по типу IClonable с единственным методом Clone. И все ваши классы которые должны уметь копироваться просто его реализуют. Проблема в том что по умолчанию в delphi интерфейсы не облегченные. И поэтому всем таким классам надо писать заглушки или унаследоваться от TSingletonImplementation.
Если вы хотите клонировать чужие классы, то или чтото не так в вашей архитектуре или надо в них влезать.
Для этого уже придуман TPersistent.Assign
...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39795022
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2X-CiteСуть класса в том, что он закрытый к изменению извне. И что у него внутри никому не известно. Поэтому только он сам себя имет право копировать. Обычно для этого вводится интерфейс по типу IClonable с единственным методом Clone. И все ваши классы которые должны уметь копироваться просто его реализуют. Проблема в том что по умолчанию в delphi интерфейсы не облегченные. И поэтому всем таким классам надо писать заглушки или унаследоваться от TSingletonImplementation.
Если вы хотите клонировать чужие классы, то или чтото не так в вашей архитектуре или надо в них влезать.
Для этого уже придуман TPersistent.Assign
То что он придуман это хорошо, но придуман он плохо..

В каком-то месте у меня есть некий класс, как узнать без явного вызова Assign и получения Exception умеет ли он себя клонирвать...

Странно создавать новый экземпляр и ему передавать как-ой то экземпляр, чтобы словить exception что не реализован и потом разрушить этот экземпляр..

Логичнее у базового проверить умеет ли он Clone и если умеет, то получить новый экземпляр-копию.

Код: 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.
  var Source := TObject.Create();
  try
    if Source is IClonable then
      Dest := IClonable(Source).Clone()
    else
      raise Exception.Create('expected IClonable');
    SendDestToSome(Dest); // там его и освобдят, а лучше клон будет там.
  finally
    Source.Free();
  end;


  var Source := TObject.Create();
  try
    var Dest := TObject.Create();
    try
      try
        Dest.Assign(Source);
      except
        on E: EConvertError do
          raise Exception.Create('expected Assigned');
      end;
    except
      Dest.Free();
      raise;
    end;
    SendDestToSome(Dest); // там его и освободят, а лучше клон будет там.
  finally
    Source.Free();
  end;

...
Рейтинг: 0 / 0
Как создать копию(клон) объекта ?
    #39795250
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Любой наследник TPersistent должен уметь Assign. Ну а детали зависят от твоих нюансов
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как создать копию(клон) объекта ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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