PDA

Ver la Versión Completa : Método free dentro de create


jam
09-03-2007, 16:55:56
Esto es una curiosidad que tengo:

¿Se podría llamar al método free dentro del constructor create?

procedure myclass.create(par:integer)
begin
inherited create(par);
...
if par<0 then
begin
inherited free;
raise exception.create('par<0');
end;
...
end;
...
myclassvar=myClass.create(-1);


Imaginaros que tengo que crear una clase, y que su constructor recibe un parámetro pero que en el caso de que no sean correcto lanze una excepción
y salga del constructor.
Si par<0 ¿qué valor recibe myclassvar?.
¿Hay alguna forma de asignar a myclassvar nil sin utilizar una función adicional?

Gracias.

Lepe
09-03-2007, 18:22:54
Al método create no se le debe pasar parámetros, solamente aquel que necesite para crearse el objeto. Ese valor "par" lo puedes incluir como una propiedad del componente..

Precisamente la comprobación de si par es mayor que cero, lo debería hacer el programa principal, no tu clase.

Respecto a tu duda, creo que no existe nada, porque estas "saltándote" la filosofía POO.

Edito:

type
EmyClass = class (Exception);

TmyClass = Class(TObject)
private
Fpar:integer;
procedure SetPar(Value:integer);
public
property Par :integer read Fpar write SetPar
end;

...
procedure TmyClass.SetPar(Value:integer);
begin
if Value < 0 then
raise emyClass.CreateFmt('El valor %d debe ser mayor que cero',[Value]);
else
begin
Fpar := Value;
....
end;
end;


myClass = TmyClass.Create;
try
myclass.par := -1;
except
on E :EmyClass then
Freeandnil(myclass);
end;

Saludos.

seoane
09-03-2007, 18:41:49
Según nos cuenta la ayuda de Delphi:

If an exception is raised during execution of a constructor that was invoked on a class reference, the Destroy destructor is automatically called to destroy the unfinished object.

Es decir, con solo provocar una excepción el método Destroy es llamado de forma automática. En cuanto a lo de asignar el valor nil, basta con que se lo asignes antes de llamar al método Create, si se produce una excepción el valor no se cambiara.

Aunque personalmente me gusta mas el modelo que plantea Lepe.

Lepe
09-03-2007, 19:56:25
Pues eso no lo sabía, gracias por el apunte seoane. Aunque no creo que esté pensado para abusar de ello.

¿Qué sentido tiene enviar a crear algo si podemos omitir ese tiempo de creación?

Es lo mismo que las excepciones:
- Puedes dejar que ocurran sin más: StrToInt('');
- O puedes prevenirlas usando otras técnicas StrToIntDef, TryStrToInt, etc.

En este caso yo primero preguntaba:

var value:integer;
begin
myClass := nil;
if Value > 0 then
begin
myClass := TmyClass.Create;
Par := Value;
end;


Saludos

jam
09-03-2007, 22:37:18
Bueno, ojeando la vcl se pueden encontrar varios ejemplos:

{ TFileStream }

constructor TFileStream.Create(const FileName: string; Mode: Word);
begin
if Mode = fmCreate then
begin
FHandle := FileCreate(FileName);
if FHandle < 0 then
raise EFCreateError.CreateResFmt(@SFCreateError, [FileName]);
end else
begin
FHandle := FileOpen(FileName, Mode);
if FHandle < 0 then
raise EFOpenError.CreateResFmt(@SFOpenError, [FileName]);
end;
end;


aquí se puede ver que se lanzan exepciones, yo lo que quería saber es si hay alguna alternativa a
try
fn:=Tfilestrem.create('fichero que no existe',fmopen)
except
fn:=nil;
end;