Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как создать копию(клон) объекта ? / 18 сообщений из 18, страница 1 из 1
30.03.2019, 17:36
    #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
30.03.2019, 17:48
    #39794103
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как создать копию(клон) объекта ?
Maxim.Kздесь д.б. реальный тип объекта aSrc

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

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

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

Sure?
...
Рейтинг: 0 / 0
30.03.2019, 19:21
    #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
30.03.2019, 23:11
    #39794160
Maxim.K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как создать копию(клон) объекта ?
loww
Код: pascal
1.
2.
3.
4.
  TMyObject = class (TPersistent)
  ...
  Clone := TMyClass(M.ClassType).Create;
  ...  


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

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

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

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

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

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

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

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

отлично! В таком случае червяки и их норы будут отсутствовать в .Assign и в .GetHashCode
...
Рейтинг: 0 / 0
01.04.2019, 18:31
    #39794775
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как создать копию(клон) объекта ?
Можно тупо скопировать занимаемый объектом участок памяти. Но это грязно и чревато
...
Рейтинг: 0 / 0
01.04.2019, 19:56
    #39794825
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как создать копию(клон) объекта ?
Суть класса в том, что он закрытый к изменению извне. И что у него внутри никому не известно. Поэтому только он сам себя имет право копировать. Обычно для этого вводится интерфейс по типу IClonable с единственным методом Clone. И все ваши классы которые должны уметь копироваться просто его реализуют. Проблема в том что по умолчанию в delphi интерфейсы не облегченные. И поэтому всем таким классам надо писать заглушки или унаследоваться от TSingletonImplementation.
Если вы хотите клонировать чужие классы, то или чтото не так в вашей архитектуре или надо в них влезать.
...
Рейтинг: 0 / 0
02.04.2019, 10:21
    #39794990
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как создать копию(клон) объекта ?
X-CiteСуть класса в том, что он закрытый к изменению извне. И что у него внутри никому не известно. Поэтому только он сам себя имет право копировать. Обычно для этого вводится интерфейс по типу IClonable с единственным методом Clone. И все ваши классы которые должны уметь копироваться просто его реализуют. Проблема в том что по умолчанию в delphi интерфейсы не облегченные. И поэтому всем таким классам надо писать заглушки или унаследоваться от TSingletonImplementation.
Если вы хотите клонировать чужие классы, то или чтото не так в вашей архитектуре или надо в них влезать.
Для этого уже придуман TPersistent.Assign
...
Рейтинг: 0 / 0
02.04.2019, 11:18
    #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
02.04.2019, 15:40
    #39795250
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как создать копию(клон) объекта ?
Любой наследник TPersistent должен уметь Assign. Ну а детали зависят от твоих нюансов
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как создать копию(клон) объекта ? / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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