Newsgroup: it.comp.lang.delphi
Titolo: warning

Quando faccio una cosa simile:
type base = class
    protected
        procedure b; virtual;
end;
type derivata = class(base)
    public
        procedure b; override;
 end;
mi viene segnalato un warning dal compilatore poichè dice che il metodo b
nella classe base era dichiarato come protetto e  invece nella classe
derivata è diventato pubblico.
Questo fatto ha qualche controindicazione oppure è solo un messaggio di cui
posso fare a meno?..e se  così come posso eliminare questo warning?
Grazie.

 Grazie.
Prego,
Andrea

 ha scritto nel messaggio
news:9eu76p$771$1...@fe1.cs.interbusiness.it...

La sezione -protected- in una dichiarazione di classe contiene quei campi,
metodi e proprietà che sono visibili all'interno della classe stessa e ai
discendenti della classe. Il vantaggio più grande è quello di poter inserire
metodi non richiamabili da un'istanza della classe, ma che siano visibili a
livello di implementazione alle classi discendenti per poter "scavalcare"
con la direttiva <override> tali metodi allo scopo di alterare o estendere
le funzionalità della classe. Un secondo utilizzo molto frequente è quello
di dichiarare nella sezione -protected- le proprietà di una classe base, che
verranno successivamente rese -public- oppure -published- nelle classi
discendenti a seconda delle esigenze specifiche (guarda, ad esempio, i casi
di TCustomLabel e TLabel, TCustomEdit e TEdit....ecc. all'interno della
VCL). Perchè viene usato questo procedimento? Il motivo è semplice: non puoi
abbassare/diminuire la "visibilità" di un campo, metodo o proprietà; se una
classe mette a disposizione una proprietà nella sezione -public-, viene
generato un warning se tenti di spostarla in sezioni meno visibili (private
e protected), poichè non serve a nulla. Nel tuo caso, il warning sta ad
indicarti che hai dichiarato e implementato un metodo che era "protetto"
nella classe base, ma questo viene reso pubblico nella discendente e quindi
richiamabile anche tramite un'istanza di quest'ultima. Se il metodo è stato
introdotto come "protected" nella classe base, evidentemente il
programmatore originale (che forse sei tu.... :-D) voleva rendere
estendibile la classe senza però rendere accessibile il metodo alle istanze;
la tua operazione aumenta la visibilità del metodo nelle classi discendenti
e quindi lo rende richiamabile anche dalle semplici istanze, e questo
rappresenta un incongruenza logica che Delphi sa potrebbe portare facilmente
alla generazione di errori...e per questo motivo ti segnala il warning. Per
risolvere il problema, devi decidere attentamente se il tuo metodo è
richiamabile o no da un'istanza e riportarlo nella classe base e nelle
classi discendenti all'interno della medesima sezione.
--
/\/\arco Breveglieri (
ma...@abls.it
)
· SINTESI S.r.l. (
www.sintesi.com
)
· ABLS Team (
www.abls.it
)

..e se  così come posso eliminare questo warning?
non lo so ...
Ciao,
Alan Solo

 mi viene segnalato un warning dal compilatore
Il codice che hai scritto non dovrebbe produrre alcun warning: e' il
normale metodo per passare da TCustomXxxx a TXxxx e non vedo perche' il
compilatore debba metterci il becco (tantomeno con un warning).
Ho provato a riprodurlo (il warning) e non ci sono riuscito. Vuoi per
favore postare il messaggio esatto che ti ritorna il compilatore e la riga
di sorgente da cui origina il messaggio?
Se TDerivata.B non avesse l'override, allora avresti effettivamente un
warning (vai sulla finestra dei messaggi, premi F1 e ti viene spiegato il
perche').
Se questo e' il caso, per tacitare il warning (cioe' se _vuoi_
effettivamente nascondere il metodo della classe base) basta usare la
direttiva reintroduce.
Saluti
Paolo Arosio

 ha scritto nel messaggio
news:9f7dou$2gaav$1...@ID-30644.news.dfncis.de...


 Il motivo per cui viene segnalato il warning č dovuto al fatto che si
sta
A me *non* viene segnalato un warning. A te si'?
Saluti
Paolo Arosio

 > Il motivo per cui viene segnalato il warning è dovuto al fatto che si


> Mi è successo una volta sola tempo fa, poichè avevo commesso
quell'errore; [...]<<
Quale errore?
Allego il mio esempio: compila (ovviamente senza alcun warning) e gira
correttamente.
D5 Pro Upd1 (Build 6.18)
Saluti
Paolo Arosio
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
  StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private    { Private declarations }
  public     { Public declarations }
  end;
  TBase = class
    protected
      procedure B; virtual;
  end;
  TDerived = class(TBase)
    public
      procedure B; override;
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var D1: TDerived;
begin
  D1 := TDerived.Create;
  try
    D1.B;
  finally
    D1.Free;
  end;
end;
{ TBase }
procedure TBase.B;
begin
  ShowMessage('Classe base');
end;
{ TDerived }
procedure TDerived.B;
begin
  inherited;
  ShowMessage('Classe derivata');
end;
end.

 ha scritto nel messaggio
news:9f884g$2okkn$1...@ID-30644.news.dfncis.de...


dovrebbe postare la propria porzione di codice da verificare...
Non e' che state invertendo tutto l'ambaradan?
Classe1 
public
  pippo
ClasseDerivata
private 
  Pippo
Cosi' il compilatore genera il warning (come logico).
Ciao,
Massimo.
-- 
"Ciao Rex, che cavolo di situazione eh? Due dentro, due fuori, puo' succedere di tutto!"

 Cosi' il compilatore genera il warning (come logico).
a me in questo caso genera un Hint: 'Overriding virtual method Derivata.B
has lower visibility than base class'
L'unico caso in cui ottengo (e devo) ottenere un warning e' se levo
l'override, dato che in questo caso levo il metodo dalla VMT
(spannometricamente e per intenderci): inherited all'interno di Derivata.B
non avrebbe senso.
Dall'help di D5: "Overriding versus hiding"
"
If a method declaration specifies the same method identifier and parameter
signature as an inherited method, but doesn't include override, the new
declaration merely hides the inherited one without overriding it. Both
methods exist in the descendant class, where the method name is statically
bound. For example,
type
  T1 = class(TObject)
    procedure Act; virtual;
  end;
  T2 = class(T1)
    procedure Act;  // Act is redeclared, but not overridden
  end;
var
  SomeObject: T1;
begin
  SomeObject := T2.Create;
  SomeObject.Act;  // calls T1.Act
end;
"
E infatti:
  TBase = class
    protected
      procedure A; virtual;
    public
      procedure B; virtual;
  end;
  TDerived = class(TBase)
    public
      procedure A;
    protected
      procedure B; override;
  end;
La dichiarazione di TDerived.A genera un warning, il cambio di visibilita'
di B genera solo un hint. Per *non* avere warning devo mettere reintroduce
su TDerived.A.
Saluti
Paolo Arosio

compilatore debba metterci il becco (tantomeno con un warning).
già, in effetti ho provato e non mi da nessun warning...
posso quasi giurare che mi è successo, ora con D5 non da nessun
warning... forse con il 4? (che versione hai/avete?)
Ciao,
Alan Solo


Perchè dici che non ha senso richiamare da un metodo non-virtual l'omonimo
metodo tramite 'inherited'?


 warning... forse con il 4? (che versione hai/avete?)
Non per essere ripetitivo, ma al di la' della domanda originale, non mi
pare che possano aver cambiato il compilatore al punto tale che i
meccanismi dell'ereditarieta' generino warning per un *aumento di
visibilita'* di un metodo. L'unico caso in cui un warning _secondo la
documentazione che ho letto_ deve essere emesso (da qualcosa di simile
allo spezzone di codice del msg originale) e' quando in una classe
derivata si ha un metodo con la stessa signature di un metodo *virtuale*
della classe base senza la direttiva override (168. Method '<name>' hides
virtual method of base type '<name>').
Cito dall'help:
Pagina "Visibility of class members"
"You can increase the visibility of a member [campo, metodo o proprieta']
in a descendant class by redeclaring it, but you cannot decrease its
visibility. For example, a protected property can be made public in a
descendant, but not private. Moreover, published members cannot become
public in a descendant class";
Qui sotto riproduco il contenuto di un ulteriore provino compilato e fatto
girare con D3 (pro) Build 5.83.
Saluti
Paolo Arosio
// il terzo bottone chiama (esplicitamente) T1.A, che altrimenti
// non viene neppure compilata
type
  T0 = class
    private
     FI: integer;
    protected
      procedure A; virtual;
      property I: integer read FI write FI;
    public
      procedure B; virtual;
  end;
  T1 = class(T0)
    private
      property I;
    protected
      procedure A;
      procedure B; override;
  end;
  TForm1 = class(TForm)
    btnA: TButton;
    btnB: TButton;
    btnT1dotA: TButton;
    procedure btnAClick(Sender: TObject);
    procedure btnBClick(Sender: TObject);
    procedure btnT1dotAClick(Sender: TObject);
  private    { Private declarations }
  public     { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.btnAClick(Sender: TObject);
var aT: T0;
begin
  aT := T1.Create;
  try
     aT.A;
  finally
     aT.Free;
  end;
end;
procedure TForm1.btnBClick(Sender: TObject);
var aT: T0;
begin
  aT := T1.Create;
  try
     aT.B;
  finally
     aT.Free;
  end;
end;
procedure TForm1.btnT1dotAClick(Sender: TObject);
var aT: T0;
begin
  aT := T1.Create;
  try
     T1(aT).A;
  finally
     aT.Free;
  end;
end;
{ T0 }
procedure T0.A;
begin
  ShowMessage('Metodo A Classe base; I = '+inttostr(I));
end;
procedure T0.B;
begin
  ShowMessage('Metodo B Classe base; I = '+inttostr(I));
end;
{ T1 }
procedure T1.A;
begin
  inherited;
  I := I+1;
  ShowMessage('Metodo A Classe derivata; I = '+inttostr(I));
end;
procedure T1.B;
begin
  inherited;
  I := I+1;
  ShowMessage('Metodo B Classe derivata; I = '+inttostr(I));
end;


Ho scritto una stupidata:
L'ho rivisto ed in effetti, se il metodo che chiama inherited viene
eseguito, viene eseguito anche l'inherited. Il problema e' che il metodo
della classe derivata e' fuori dalla lista di esecuzione dei metodi
virtuali.
v. esempi nella mia risposta al post di A.Solo
--
Saluti
Paolo Arosio

virtual method of base type '<name>').
ok, allora forse l'autore del thread si era dimenticato un "override"
;)
[snip codice]
ripensandoci in effetti un warning per un aumento di visibilità non
avrebbe proprio senso anche perchè ereditando da un TCustomQualcosa
si avrebbero decine di warning (inutili, appunto)
Ciao,
Alan Solo