Копиране на обект

15 отговора 398 прегледа
#1

Копиране на обект

Някой знае ли дали е възможно да се копира обект от един клас в обект от същия клас?

AquilaX

____________
умният знае кога да говори, мъдрият знае кога да мълчи
Отговор
в отговор на AquilaX #2

Re: Копиране на обект

Ако класа поддържа Assign

Отговор
в отговор на NDeu #3

Re: Копиране на обект

Мдамм това да но може ли се направи нещо от рода на

procedure CopyObject(Source:TObject; var Destination:TObject);

AquilaX

____________
умният знае кога да говори, мъдрият знае кога да мълчи
Отговор
в отговор на AquilaX #4

Re: Копиране на обект - има...

procedure CopyObject(Source:TObject; var Destination:TObject);
begin
Destination.Assign(Source);
end;

;-)))))

---
Е т'ва е живот!
Отговор
в отговор на AquilaX #5

Re: Копиране на обект

от хелпа на Delphi:

TPersistent.Assign

Copies the contents of another, similar object.

procedure Assign(Source: TPersistent); virtual;

Description

Call Assign to copy the properties or other attributes of one object from another. The standard form of a call to Assign is

Destination.Assign(Source);

which tells the Destination object to copy the contents of the Source object to itself.

Most objects override Assign to handle the assignment of properties from similar objects. When overriding Assign, call the inherited method if the destination object can’t handle the assignment of properties from the class of the Source parameter.

If no overridden Assign method can handle the assignment of properties from Source, the method implemented in TPersistent calls the source object’s AssignTo method. This allows the source object to handle the assignment. If the Source object is nil, TPersistent.Assign raises an EConvertError exception.

In general, the statement “Destination := Source” is not the same as the statement “Destination.Assign(Source)”. The statement “Destination := Source” makes Destination reference the same object as Source, whereas "Destination.Assign(Source)" copies the contents of the object referenced by Source into the object referenced by Destination.

Note: The types of some properties are also objects. If these properties have write methods that use Assign to set the value of the property, then in these cases the statement "Destination := Source" is the same as "Destination.Assign(Source)".

ет ти и сампле:

type
TMyObject = class(TComponent)
private
fNewIntField : Integer;
fNewStrField : String;
fNewObjField : TComponent;
public
procedure Assign(Source : TPersistent); override;
property NewIntField : Integer read fNewIntField write fNewIntField;
property NewStrField : String read fNewStrField write fNewStrField;
property NewObjField : TComponent read fNewObjField write fNewObjField;
end;
...
procedure TMyObject.Assign(Source: TPersistent);
begin
inherited;
fNewIntField := TMyObject(Source).NewIntField;
fNewStrField := TMyObject(Source).NewStrField;
fNewObjField.Assign(TMyObject(Source).NewObjField);
end;


--------------------------------------
Започва Път от моят праг...
Отговор
в отговор на PhantomAS #6

... ама не така!

TObject(AnyObject).Assign?
:-)

--------------------------------------
Започва Път от моят праг...
Отговор
в отговор на Hateras #7

Re: Копиране на обект

Това и аз го видях и assign изглежда много примамливо докато не погледниш че метода трябва да се предефинира за всеки клас. Аз търся в случая униврсиализъм но май това което търся не е възможно. Някакви идеи отоло TMemoryStream ???

AquilaX

____________
умният знае кога да говори, мъдрият знае кога да мълчи
Отговор
в отговор на AquilaX #8

Re: Копиране на обект

искаш хем да спиш, хем да работиш?
не, няма да стане! ;-)

какво за TMemoryStream? искаш да си направиш копие?

--------------------------------------
Започва Път от моят праг...
Отговор
в отговор на AquilaX #9

Re: Копиране на обект

Виж нещо от сорта, в случая използвам файл де, но може да си го интерпретираш
procedure TBackup.SaveToTextFile(const FileName: string);
var
ms: TMemoryStream;
fs: TFileStream;
CipherManager1: TCipherManager;
begin
// zapiswane
fs:= TFileStream.Create('_tmp_', fmCreate or fmOpenWrite);
ms:= TMemoryStream.Create;
try
try
ms.WriteComponent(Self);
ms.position:= 0;
ObjectBinaryToText(ms, fs);
except
on e: exception do
;
end;
finally
ms.Free;
fs.free;
end;
end;

procedure TBackup.LoadFromTextFile(const FileName: string);
var
ms: TMemoryStream;
fs: TFileStream;
CipherManager1: TCipherManager;
begin
// zarejdane
fs:= TFileStream.Create('_tmp_', fmOpenRead);
ms:= TMemoryStream.Create;
try
try
ObjectTextToBinary(fs, ms);
ms.position:= 0;
ms.ReadComponent(Self);
except
on e: exception do
;
end;
finally
ms.Free;
fs.free;
end;
DeleteFile('_tmp_');
end;

Отговор
в отговор на Bятъp #10

Re: Копиране на обект

CipherManager1-а не ти трябва разбира се

Отговор
в отговор на Bятъp #11

Re: Копиране на обект

Понеже поорязах функциите за да постна което трябва се получиха малко шибани... но идеята е ясна

Отговор
в отговор на Bятъp #12

Re: Копиране на обект

това - ако държиш да си имаш копие на некъв стреам във файл, иначе е по-простичко:
TStream.CopyFrom

--------------------------------------
Започва Път от моят праг...

Редактирано от Hateras на

Отговор
в отговор на Hateras #13

Re: Копиране на обект

Само дадох идея...

Видях да язди през реки, те седем са на брой...
Отговор
в отговор на AquilaX #14

Re: Копиране на обект

Taka ili inache ako imash agrigirani obekti gaza si da saderesh ne mojesh da naprawish generalizirano copirane. Za twa si prawish copy constructor i LoadFromStream/SaveToStream ili ako si mazohistichen prenapiswah assign (koeto te zadaljawa da nasledish ot TPersistent).

------------------------------
I got a COMPILER, and I'm not afraid to use it!
Отговор
в отговор на SDR #15

Re: Копиране на обект

За съжаление и аз стигнах до този извод но надеждата умира последна :)

Благодаря на всички за мненията.

AquilaX

____________
умният знае кога да говори, мъдрият знае кога да мълчи
Отговор
в отговор на AquilaX #16

Някакво решение

Може да се направи така:
Procedure CreateCopy(ASource : TObject; Out ADest);

Begin
TObject(ADest) := ASource.ClassType.Create;
Move(Byte(PChar(ASource)^), Byte(PChar(ADest)^), ASource.ClassType.InstanceSize);
End;



Обаче това естествено няма да работи, ако в класа се заделя памет,
независимо дали заделянето е в явен (New, GetMem) или неявен (long String, динамичен масив, създаване на обект) вид.
Все пак е някакво решение. Ако става дума за твои класове, String-овете трябва да са String[xx] и всички масиви да са статични. Ако създаваш обекти в тях или заделяш памет - не става.

Отговор