Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008
-
27 juil. 2007 à 17:41
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008
-
11 août 2007 à 22:14
Bonjour a tous!
J'ai un probleme avec une fonction retournant un objet. D'habitude pour les fonctions retournant un objet, je n'ai pas de soucis. Voilà un exemple bateau qui fonctionne :
C'est pourtant l'equivalant du TStringList avec un TDataSource, mais ca ne fonctionne pas! L'erreur vient de la methode Assign du TDataSource. Bien sur une solution serait :
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008 11 août 2007 à 22:14
Bonsoir a tous!
Je viens proposer la solution que j'ai finnallement adoptée. Après pas mal de recherche et mon ami FastMM4 qui m'indiquait les eventuelles fuites de mémoire, j'ai trouvé la solution qui resout mon problème.
Le problème de départ était de savoir comment bien détruire les objet créer dans une fonction. J'ai abandonné la piste de la redefinition du Assign qui aurair pu resoudre ce probleme en copiant un objet dans un autre.
Au final voilà comment je m'y prend :
var MyObjectArray : Array of TMyObject ;
function TBlabla.getObject : TMyObject;
var index : integer;
obj: TMyObject;
begin
obj:= TMyObject.Create ;
index := length( MyObjectArray ) ;
SetLength(MyObjectArray , index + 1) ;
MyObjectArray[index] := obj ;
Result := obj ;
end;
procedure TBlabla.DestroyObject;
var index : integer ;
l : integer ;
begin
l := length( MyObjectArray ) ;
if l = 0 then Exit ;
for index := 0 to l do
begin
if Assigned( MyObjectArray[index] ) then
MyObjectArray[index].Free ;
end;
end;
Donc en faite je sauvegarde tout mes objet créer dans un tableau, et je me charge de les détruire à la fin de mon programme. C'est pas tout a fait ce que je souhaitais faire au depart, mais ça permet de bien detruire les objet crée dans une fonction.
Si jamais ça peut permetre d'aidé quelqu'un qui est confronté au même probleme!
Merci en tout cas a ceux qui auront tenté de m'aidé!
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20123 27 juil. 2007 à 20:18
Bonsoir
Un petit rappel :
DBGrid1.DataSource := tmpSource ;
n'est pas identique à
DBGrid1.DataSource.Assign( tmpSource );
Dans le premier cas, l'opérateur d'affectation := fait que DataSource désignera le même objet que tmpSource, tandis que dans le second cas la méthode Assign ne fait que recopier le contenu référencé par tmpSource dans un autre objet, ici DataSource, donc celui ci doit être déjà créé.
P.S. Crée un DBGrid auquel tu affectes un DataSource, puis un second DataSource. Et essayes le code suivant
DBGrid1.DataSource.Assign( DataSource1 );
Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008 28 juil. 2007 à 01:01
Bonsoir!
Merci pour vos reponse...
En faite je connais la distinction entre l'affectation et l'assignation. Mais je crois que j'ai du mal m'exprimer dans mon premier post.
La methode Assign pas defaut dans le TPersistant ne fais qu'un appel a la methode AssignTo:
procedure TPersistent.Assign(Source: TPersistent);
begin
if Source <> nil then Source.AssignTo(Self) else AssignError(nil);
end;
Le probleme est que le TDataSource n'implemente pas la methode AssignTo, d'où l'exception généré. En gros dans l'exemple avec un TStringList il n'y a pas de soucis car la methode Assign est surchargé, mais le TDataSource ne surcharge ni Assign ni AssignTo
Donc la question était plutot de savoir comment faire pour creer une fonction qui retourne un TDataSource sans fuite de mémoire (et sans implementé à la main un AssignTo au TDataSource). Ou plus globalement comment copier un objet dans un autre sans passé par Assign.
En esperant que j'ai pu etre un peu plus clair (mais il est tard donc c'est pas gagné ) Merci d'avance
Vous n’avez pas trouvé la réponse que vous recherchez ?
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 28 juil. 2007 à 01:14
function TForm1.GetList : TStrings;
begin
result := TstringList.Create;
with Result do
begin
BeginUpdate;
try
Add('1');
Add('2');
finally
EndUpdate;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var TmpList : TStrings;
begin
TmpList := GetList;
ListBox1.Items.Assign( TmpList );
TmpList.Free;
end;
et
si on regarde la structure de TDataSource, aucune methode Assign ou
AssignTo n'est surchargée ... en gros, seul les données de l'ancetre
(TComponent) sont copiées dans la source ...
alors que pour TStrings (Ancetre de TStringList) on y trouve :
procedure TStrings.Assign(Source: TPersistent);
begin
if Source is TStrings then
begin
BeginUpdate;
try
Clear;
FDefined := TStrings(Source).FDefined;
FNameValueSeparator := TStrings(Source).FNameValueSeparator;
FQuoteChar := TStrings(Source).FQuoteChar;
FDelimiter := TStrings(Source).FDelimiter;
AddStrings(TStrings(Source));
finally
EndUpdate;
end;
Exit;
end;
inherited Assign(Source); // Vers TPersistent.Assign
end;
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 28 juil. 2007 à 01:16
ah j'avais pas vus ta reponse...
Donc la question était plutot de savoir comment faire pour creer une
fonction qui retourne un TDataSource sans fuite de mémoire (et sans
implementé à la main un AssignTo au TDataSource). Ou plus globalement
comment copier un objet dans un autre sans passé par Assign.
tu peu faire :
procedure TForm1.GetDataSource(DataSource : TDataSource);
begin
if not Assigned(DataSource) then
exit;
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 28 juil. 2007 à 01:21
sinon pour deriver TDataSource c'est assé simple :
uses .... , DB;
type
TDataSource = class(DB.TDataSource)
public
procedure Assign(Source : TComponent); override;
end;
TForm1 = class(TForm)
...
end;
implementation
procedure TDataSource.Assign(Source : TComponent);
begin
if Source is TDataSource then
begin
with Source do
begin
Self.{property} := {source property}
end;
end else
inherited Assign(Source);
end;
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 5 août 2007 à 23:21
Petit rappel à l'ordre !
@ Sat83 : valides-tu les réponses oui ou non ?
Par politesse, il serait bon de donner signe de vie à ceux qui se sont décarcassés pour toi.
May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
http://www.afipa.net/
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008 6 août 2007 à 11:56
Bonjour bonjour!
Ce n'est pas du tout par impolitesse que je n'ai pas repondu aux messages laissés sur ce post!
Et bien evidemment je remercie ceux qui ont pris la peine de lire mon message et proposé une solution à mon problème.
Pour le moment je n'ai pas eu le temps de continué mon projet, donc en
attendant je laisse ce post ouvert à d'autres idées éventuelles. Sinon,
je pense que j'adopterais la solution de Foxi ( a savoir dériver la
methode Assign ) meme si je préfererais l'éviter.
Je n'ai pas cliqué sur "reponse accepté" au cas où une autre solution serait proposée pour copier un objet dans un autre.
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008 10 août 2007 à 11:21
Re-bonjour a tous !
Alors aujourd'hui je me suis motivé pour me relancé dans mon mini projet et donc tenté de résoudre mon probleme de copie d'objet dans un autre.
J'ai donc tenté d'utilisé les deux solutions proposé par Foxi, mais le problème malheureusement persiste!
J'ai donc dérivé la classe TDataSource pour pouvoir implémenté la methode Assign, jusque là pas de problème. Le problème c'est qu'il y a des objets dans les propriété du TDataSource (TDataSet en locurance) qui ne possède pas de methode Assign !
Donc en gros, en utilisant une simple affectation pour TDataSet dans le Assign de TDataSouce, les deux objets auront leurs propriété DataSet pointant sur les même objet ! Alors que ce que je souhaiterais c'est avoir deux objet completement indepandant.
Je sais, ca devient compliqué, moi même je m'y perd dans mes explications !
Je ne sais pas si il a vraiment une solution a ce que je veut faire!
Mais si jamais vous en avez d'autres a proposé, n'hesité pas!