2016-08-25 32 views
5

mam metodę z parametrem jako przedmiot (sniped kodu poniżej):Delphi: Jak uwolnić obiekt utworzony dynamicznie jako parametr metody

TMyObject=class(TObject) 
    constructor Create(); 
    destructor Destroy();override; 
end; 

implementation 

function doSomething(x:TMyObject):integer; 
begin 
    //code 
end; 

procedure test(); 
var 
    w:integer; 
begin 
    w:=doSomething(TMyObject.Create); 
    //here: how to free the created object in line above? 
end; 

Jak zniszczyć obiekt utworzony wewnątrz zwaną metodą doSomething zewnątrz Ta metoda?

+10

nie bądź leniwy. Utwórz zmienną! – smooty86

+0

tak, zrobiłem to, ale myślę, że jest to możliwe w inny sposób? – Artik

+0

używać interfejsów zamiast obiektów :) – kami

Odpowiedz

8

Aby zwolnić instancję obiektu, należy podać odniesienie do niego, pod którym można zadzwonić pod numer Free().

Ponieważ tworzysz instancję obiektu w miejscu jako parametr, jedyne odniesienie, które będziesz mieć, to parametr znajdujący się wewnątrz parametru doSomething().

albo trzeba Free go wewnątrz doSomething() (co jest praktyką nie radzę robić):

function doSomething(x: TMyObject): Integer; 
begin 
    try 
    //code 
    finally 
    x.Free; 
    end; 
end; 

Albo trzeba utworzyć dodatkową zmienną w test(), przekazać go do doSomething(), a następnie Free go po doSomething() powraca:

procedure test(); 
var 
    w: Integer; 
    o: TMyObject 
begin 
    o := TMyObject.Create; 
    try 
    w := doSomething(o); 
    finally 
    o.Free; 
    end; 
end; 

Choć może się wydawać że za pomocą odniesienia liczone obiektu pozwoli na utworzenie obiektu w miejscu i niech liczenia odniesienia uwolnić obiekt tego rodzaju konstrukcji może nie działać z powodu następującego problemu kompilatora:

The compiler should keep a hidden reference when passing freshly created object instances directly as const interface parameters

Potwierdzają to przez byłego inżyniera Embarcadero kompilatora, Barry Kelly, w odpowiedzi StackOverflow:

Should the compiler hint/warn when passing object instances directly as const interface parameters?

+1

Będzie działać, jeśli parametr interfejsu nie jest "const" lub jeśli jest przekazywany z 'jak ISomeInterface'. Zobacz moje inne komentarze. Twój komentarz dotyczący zerwania interfejsów jest trochę paniczny i niezupełnie prawdziwy. –

+0

@RudyVelthuis Tak, to działa tak. Ale jest to bardzo kruchy kod, ponieważ jeśli zmienisz sygnaturę metody, możesz złamać kod w zupełnie niezwiązanym miejscu - wywołanie metody. Nie radziłbym tego. A interfejsy są zepsute, ponieważ wielu programistów Delphi ciągle pisze kod, który jest zepsuty przez powyższy błąd. Nawet doświadczeni. Od czasu do czasu muszę informować ludzi o tym błędzie. –

+3

Zmiana sygnatury jest zawsze złym pomysłem. Ale używając 'as', nigdy nie jest kruchy, z lub bez' const'. –