Newsgroup: it.comp.lang.c++
Titolo: Ereditarietà di interfaccia

Sto leggendo il tutorial di Paolo Marotta, l'"Appendice A", al quale
volevo chiedere una cosa per vedere se ho capito bene. Ad un certo punto
trovo scritto:
class Interface {
    public:
      void Foo() {}
      double Sum(int a, double b) {}
  };
Non sarebbe meglio che le due funzioni non avessero corpo (anche se
vuoto) ma solo dichiarazione? In questo modo il linker mi avviserebbe
immediatamente se tento di utilizzare una di queste da una classe
derivata che non le ha ancora definite.
Dico bene?
EMG

  };
Una dichiarazione di interfaccia non dovrebbe essere:
class Interface {
    public:
      void Foo() = 0;
      double Sum(int a, double b) = 0;
  };
O sbaglio?
Ciao, Giuseppe
---------------------------------------------------------------------------
_Guybrush su IRCNet canale #programmazione
ICQ: 42227764
---------------------------------------------------------------------------

 Ciao, Giuseppe
C'e qualcosa che non torna...
Non ho letto il tutorial di PM, ma credo che la dichiarazione di
un'interfaccia dovrebbe essere qualcosa del genere:
class Interface {
    public:
      virtual void Foo() = 0;
      virtual double Sum(int a, double b) = 0;
      virtual ~Interface() {}
};
Se i metodi non sono virtuali non e' possibile specializzarli...
(O forse non ho capito bene di cosa stavate parlando ?)
*Fabio*
--
I don't want to achieve immortality through my work.  I want to achieve
immortality through not dying.
                -- Woody Allen



Ciao, Giuseppe
Un metodo astratto ('puro') deve essere virtuale. 
-- 
God is Real, unless declared Integer.

Dico bene?
Si, ma perche` non segnalarmi direttamente la cosa, oltre che
giustamente chiedere anche sul NG (avere piu` pareri non
guasta)?
Ciao,
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

O sbaglio?
Non va bene, i due metodi dovrebbero essere dichiarati
anche virtual per poter scrivere una cosa simile:
class Interface {
    public:
      virtual void Foo() = 0;
      virtual double Sum(int a, double b) = 0;
 };
Ho preferito comunque un approccio che fosse indipendente dal
C++ in quanto l'argomento (appendice B e non A) era la OOP
in senso generico, sebbene gli esempi siano in C++. 
Alcuni linguaggi tipo smaltalk non distinguono
tra metodi virtuali e metodi statici, i metodi sono sempre virtual.
In generale questa distinzione viene fatta nei linguaggi compilati
per consentire un ulteriore grado di ottimizzazione.


(O forse non ho capito bene di cosa stavate parlando ?)
Si tratta di un errore piuttosto comune (e facile da fare), in effetti
raramente viene messa in evidenza l'indipendenza dei due
meccanismi.


 -----------------------------------------------------------------
*Fabio*
-- 
That's no moon...
		-- Obi-wan Kenobi

 O sbaglio?
Cosě non funziona. Funzionerebbe se i metodi fossero virtuali. Ma
avresti un inutile overhead, credo.
EMG

 };
Infatti questo è il metodo classico. Ma anche senza i metodi virtuali è
possibile utilizzare la classe base come un controllo a tempo di linking
sulla effettiva definizione nella classe derivata di tutti i metodi
dell'interfaccia. Basterebbe poi anche un solo metodo privato virtuale
astratto per rendere astratta la classe base ed impedirne quindi
l'istanziazione diretta.
EMG

Ho capito il discorso sul dichiarare virtuali i metodi. Ma non dichiarali
virtuali non è uno sbaglio. O no?


 guasta)?
Pensavo che il discorso potesse essere interessante per tutti i
partecipanti, non era assolutamente per esporre un tuo errore (anche
perché non ero sicuro fosse tale) al pubblico ludibrio. :-))) Comunque,
se vuoi cosě, la prossima volta ti scrivo in privato.
EMG

quello della classe Derivata.
D'accordo, ma tu pasi per un reference, non per l'oggetto stesso...
e` esattamente la stessa cosa che accade passando per un
puntatore... D'altronde un reference e` tutto sommato un
puntatore che si autodereferenzia.
Tutto il discorso sulla bonta` o meno di una gerarchia cosi`
fatta comunque non rientra nella discussione di cui all'appendice
del mio tutorial... quando vuoi spiegare una cosa bisogna
ricorrere ad esempi minimali, per non distrarre l'attezione
sull'argomento con altre problematiche. Bisogna andare per
gradi.


virtuali non è uno sbaglio. O no?
Non necessariamente, solo se usi puntatori a classe base per
riferire a oggetti di classe derivata perche` in questo caso l'unica
informazione che da il puntatore e` che l'oggetto puntato e`
un oggetto di classe base:
Base* P = new Derived;
P->Metodo();
al momento in cui viene invocato Metodo() il compilatore
sa solo che P punta sicuramente ad un oggetto di tipo Base.
Con approfondite analisi si potrebbe cercare di scoprire
qualcosa in piu`, ma in generale non e` possibile risalire
al tipo esatto dell'oggetto correntemente puntato.
Quindi se usi i puntatori a classe base per puntare anche oggetti di
classi derivate il virtual e` necessario, altrimenti no!
In generale comunque per non sbagliare vale la regola
di dichiarare virtual i metodi di una classe base (al piu`
perdi in efficenza, ma sicuramente non risci di invocare i metodi
sbagliati).
Nota:
  Nell'esempio precedente potevamo forzare il binding con
  P->Derived::Metodo()    (con tutti i rischi del caso se *P non
  fosse un Derived o un ulteriore sottotipo).


se vuoi cosě, la prossima volta ti scrivo in privato.
Per carita`, non e` che non voglia che tali cose siano rese pubbliche
(d'altronde non mi sono mai ritenuto infallibile), solo che una
segnalazione in e-mail mi resta anche in caso di assenza, mentre un
messaggio sul NG dopo un po' sparisce con il rischio che l'errore
sul tutorial rimanga! In sostanza in questi casi gradirei una e-mail di
segnalazione indipendentemente da una eventuale esposizione
al pubblico ludibrio :((((((
Cmq gli errori sono stati corretti, pero` se ne parla nella versione 2.2
Se scovi qualche altro orrore ti inserisco di diritto nella "Hall of
fame" del tutorial (ovvero il "libro nero" di coloro i quali hanno
segnalato orrori vari ;-) Per la verita` attualmente c'e` ne sta uno
solo cui va il merito di aver fatto una vera e propria opera di
revisione.
Paolo


 virtuali non è uno sbaglio. O no?
Sintatticamente parlando no. Potrebbe essere un errore concettuale se il
problema che sto affrontando si modella bene con una gerarchia di
classi.
EMG

Grazie a tutti e due. Ora ho le idee chiare.
