2015-04-24 2 views
0

dire que j'ai l'enregistrement suivant:TDictionary utilisant des pointeurs

type 
    TTest = record 
     test1 : TTest1; 
     test2 : TTest2; 
     test3 : TTest3; 
    end; 
    pTTest = ^TTest; 
    TDictestDictionary = TDictionary<integer,pTTest>; 
    testDictionary : TDictestDictionary 

aura-t-il suffisant pour écrire

testDictionary := TDictionary<integer,pTTest>.Create; 

puis ajoutez les articles comme:

testDictionary.AddOrSetValue(1,pValue); 

ou besoin initialiser pValue?

Mais ce qui arrive quand:

GetMem(pValue, Value); 
    testDictionary.AddOrSetValue(1,pValue); 
    FreeMem(pValue); 

seront les éléments supprimer les données pointées par pValue?

S'il vous plaît Aide

En outre, sur la même ligne de pensée, je peux avoir quelque chose comme ceci:

Type 
    myClass = class(TObject) 

    private 
    FTest : TDictestDictionary ; 

public 
    property propFTest : TDictestDictionary read getFTest() write setFTest() 

mais alors comment j'écris getFTest() setFTest()

Aide. Merci

+1

Mais pourquoi sur Terre voulez-vous stocker les pointeurs? –

+0

@Jens, parce que faire une copie des documents pourrait être inutile et difficile à maintenir? Imaginez que vous pouvez stocker les enregistrements dans un tableau simple et faire autant de * vues * que vous le souhaitez en utilisant des pointeurs. Oui, vous devez les synchroniser avec ces * vues *, mais vous devrez le faire aussi pour les * vues * ayant également des copies d'enregistrements. – TLama

+0

@JensBorrisholt sans code de pointeurs comme 'testDictionary [1] .test1 = ...' va créer une copie de l'enregistrement et n'affectera pas la valeur dans le dictionnaire. Dans de tels cas, vous devez stocker les pointeurs d'enregistrement – teran

Répondre

2

Si vous voulez vraiment stocker des pointeurs dans votre conteneur, vous devrez allouer la mémoire à un moment donné. Si vous libérez la mémoire lorsque le conteneur contient toujours une référence à cette mémoire, la référence du conteneur est inutile. Il est connu sous le nom de pointeur . Invariablement, tenir des pointeurs périmés signifie que votre code est défectueux.

Il ne me semble pas nécessaire d'utiliser des pointeurs ici. Vous pouvez déclarer le dictionnaire comme ceci:

TDictionary<Integer, TTest> 

Ce conteneur contient des copies de vos enregistrements et gère ainsi la durée de vie automatiquement.

0

Je suis d'accord David. Je ne vois aucun besoin de pointeurs ici. Utilisez une classe et un TObjectDictionary puis vous pouvez créer autant de vues que vous le souhaitez et la gestion de la mémoire est encore facile: Un TObjectDictionary possède les classes les autres TObjectDictionary ou TList<> sont juste des vues en présenant vos données différentes.

Voici une unité pour inspiration.

unit TestDictionaryU; 

interface 

uses 
    System.Generics.Collections; 

type 
    TTest1 = class 
    end; 

    TTest2 = class 
    end; 

    TTest3 = class 
    end; 

    TTest = class 
    test1: TTest1; 
    test2: TTest2; 
    test3: TTest3; 
    constructor Create; 
    destructor Destroy; override; 
    end; 

    TTestDictonary = class(TObjectDictionary<Integer, TTest>) 
    public 
    constructor Create; 
    function AddTest : TTest; 
    end; 

implementation 

{ TTest } 

constructor TTest.Create; 
begin 
    inherited; 
    test1 := TTest1.Create; 
    test2 := TTest2.Create; 
    test3 := TTest3.Create 
end; 

destructor TTest.Destroy; 
begin 
    test1.Free; 
    test2.Free; 
    test3.Free; 
    inherited; 
end; 

{ TTestDictonary } 

function TTestDictonary.AddTest: TTest; 
begin 
    Result := TTest.Create; 
end; 

constructor TTestDictonary.Create; 
begin 
    inherited Create([doOwnsValues]); 
end; 

end. 
+0

Pourquoi utiliser un cours? Sûrement c'est un record? –

+0

Afin d'éviter les pointeurs –

+0

Les enregistrements ne nécessitent pas l'utilisation de pointeurs. Pas de pointeurs avec le type dans ma réponse. –