Newsgroup: it.comp.lang.delphi
Titolo: un dubbio con i costruttori

ciao a tutto il ng.
ho questo dubbio a proposito dei costruttori chiassą se qualche *anima* mi
puņ aiutare:
una classe
TPagina = class (TObject)
private
    x : integer;
    ....
public
    ....
    constructor create; overload;
end;
constructor TPagina.create;
begin
    TObject.create;   // č giusto? oppure č superfluo?
    x := 0;
end;
grazie fin d'ora a tutti.
Roberto

 Roberto
Prego,
Andrea

 In sč č giusto, sempre tenendo conto di quanto detto su.


end;
Non ti serve fare l'"overload", basta
scrivere:
type MyClass = class
                 private
                   // membri privati...
                 public
                   constructor Create;                 
               end;
constructor MyClass.Create;
begin
  inherited Create;
  // ..
end;

Prova così:
constructor TPagina.create;
begin
  inherited;
  ..
  ..
  ..
  x := 0;
end;
Ciao Max
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

In sè è giusto, sempre tenendo conto di quanto detto su.
Che io sappia, e` sbagliato.
inherited Create e` la forma giusta.

 roberto
Prego
Andrea

 inherited Create e` la forma giusta.
Sicuramente è più "sicuro" e più chiaro.
Andrea

grazie
roberto
"Andrea Laforgia" <x@x.x> ha scritto nel messaggio
news:07vmuu8bh5697c7oo...@4ax.com...


 ha scritto nel messaggio
news:asfrk3$8i1$1...@lacerta.tiscalinet.it...



in effetti ci mette overload (pag. 63)
ma mi sono confuso io su di una cosa molto basilare.... overload si usa
quando ho un metodo o un costruttore con lo stesso nome ma con parametri di
numero e/o tipo diverso.
purtroppo mi sono un po' arrugginito ;-)
ciao
roberto

Bhe, in realtà si può fare in entrambi i modi.
In che senso ? con TObject a quale istanza ti riferisci ?

 In che senso ? con TObject a quale istanza ti riferisci ?
Quando scrivi TObject.Create, tu stai dicendo al compilatore "Eseguimi qui
il codice d'inizializzazione della classe TObject".
E poiché la classe è derivata da TObject, questo porta ad una
inizializzazione corretta, ma solo per questo.
Andrea


Quando crei una classe che discende da un'altra classe, non devi richiamare
il costruttore con una scrittura simile a questa:
======
TMyParentClass.Create()
======
poichè in questo modo non ti accerti che vengano eseguite le
inizializzazioni del costruttore della classe dalla quale erediti, ma
semplicemente crei una nuova istanza di tale classe.......
La scrittura giusta è ovviamente
======
inherited Create;
======
che nel caso di una classe che discende da TObject non deve essere
richiamata (poichè è implicita), ma è solo un caso particolare; se invece
discendiamo da un'altra classe, ad esempio di tipo TComponent, dovremo
creare un metodo costruttore compatibile con quello ereditato (per poter
fare l'override)
======
constructor Create(AOwner: TComponent); override;
======
e implementare tale metodo in un modo simile a questo
======
constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  // ... inizializzazione dei campi privati di TMyComponent
end;
======


Penso che il dubbio di Andrea Laforgia sia concreto.
In realtà, non hai bisogno di eseguire TObject.Create all'interno del
costruttore; questo provoca un memory leak, stai creando un'oggetto senza
assegnarlo ad una variabile d'istanza specifica.
Inoltre, il costruttore di TObject non è virtuale e non esegue alcuna
istruzione, per cui derivando da TObject si può anche evitare di chiamare il
metodo ereditato all'interno del nuovo costruttore. L'istanza della nuova
classe sarà comunque costruita correttamente.
Antonio

inizializzazione corretta, ma solo per questo.
Tutto sbagliato.  
Quando chiami TObject.Create stai *instanziando* un TObject, non stai
eseguendo alcun codice d'inizializzazione di alcun genitore.
Come ho gia` ripetuto piu` volte, bisogna usare:
inherited Create;
e NON:
TObject.Create;
La controprova, d'altronde, ce l'hai eseguendo il codice seguente, in
cui puoi osservare che, sostituendo inherited Create con
TObject.Create, il codice d'inizializzazione della classe madre non
viene eseguito:
type
  MyBaseClass = class
                protected
                  A: Integer;
                public
                  constructor Create;
                end;
  constructor MyBaseClass.Create;
  begin
    A := 56;
  end;
type
  MyDerivedClass = class(MyBaseClass)
                   private
                     B: Integer;
                   public
                     constructor Create;
                     procedure Show;
                   end;
  constructor MyDerivedClass.Create;
  begin
    // errato
    // TObject.Create;
    // giusto
    inherited Create;
    B := 77;
  end;
  procedure MyDerivedClass.Show;
  begin
    ShowMessageFmt('A = %d  B = %d ', [A, B]);
  end;
procedure TForm1.Button1Click(Sender: TObject);
var
  D: MyDerivedClass;
begin
  D := MyDerivedClass.Create;
  D.Show;
end;

 viene eseguito:
Ho controllato, effettivamente le cose sono cambiate dai vecchi tempi.
In ogni caso, impara a leggere, perché io avevo scritto:
"E poiché la classe č DERIVATA da TObject, questo porta ad una
inizializzazione corretta, ma solo per questo."
Il che significa che il tuo esempio non era consistente, in quanto io avevo
specificato che era figlia di TObject, quindi avresti dovuto usare la classe
genitore come di seguito:
constructor MyDerivedClass.Create;
begin
  MyBaseClass.Create;
  B := 77;
end;
In ogni caso, mandando in esecuzione l'esempio se ne deduce che il
comportamento non č quello
che mi aspettavo.
Vedi che succede, Laforgia, a dare le cose per sicure? :)
Andrea

Vedi che succede, Laforgia, a dare le cose per sicure? :)
Cioe` ? hai dato per sicura qualcosa che in realta` era sbagliata ?
Vorrei ricordarti che non e` la prima volta che ti capita.
Leggo i tuoi messaggi anche nella gerarchia Borland e mi spiace vedere
come, frequentemente, ad ogni tua risposta segua sempre quella di
qualcuno che corregge quanto stai dicendo.  
Forse dovresti fare un po` piu` attenzione a cio` che scrivi.