Newsgroup: it.comp.lang.c++
Titolo: chiamata di una funzione membro ridefinita da una classe derivata

fra poco mi sbatterete fuori da questo ng... :-))))
ho una classe
class PippoShort {
public:
	bool Funz(short Pluto);
}
e la sua derivata
class PippoInt : public PippoShort {
public:
	bool Funz(int Pluto);
}
nella definizione della funzione della classe derivata, ho tentato di
fare questo:
bool PippoInt::Funz(int Pluto)
{
	return Funz(short(Pluto));
}
ma non me lo accetta (pensa che sto tentando di fare una ricorsione,
in realtà nel mio prog non ci sono i tipi short e int, ma string e
AnsiString, che non possono castare l'uno con l'altro in maniera
indolore, per questo il compilatore si arrabbia)
ho dovuto mettere return PippoShort::Funz(short(Pluto));
]\/[ad]\/[age
"Un Maestro nell'arte della vita, non fa nessuna precisa distinzione tra lavoro
e gioco, fatica e riposo, mente e corpo, educazione e ricreazione. 
Insegue semplicemente la sua visione di Eccellenza attraverso qualunque cosa sta facendo e lascia agli altri decidere se sta lavorando o giocando. A lui sembra sempre che sta facendo entrambe le cose." - Anonimo.
.-~-.-~-. 
www.madmagelab.cjb.net
 .-~-.-~-.

 ma non me lo accetta (pensa che sto tentando di fare una ricorsione,
Dovrebbe accettarlo. Ma nota che stai (appunto) chiamando sempre
PippoInt::Funz e non, come forse pensavi, PippoShort::Funz.
Il motivo è che nello scope PippoInt:: il nome Funz risolve univocamente
a PippoInt::Funz in quanto la PippoShort::Funz è nascosta (hiding). Per
esempio dall'esterno:
PippoInt obj;
short sh;
obj.Funf(sh);
chiama tranquillamente PippoInt::Funz promuovendo sh ad intero perchè
PippoShort::Funz è nascosta.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

PippoShort::Funz è nascosta.
ah, sì?... allora mi sa che c'ho capito poco pure con
l'ereditarietà... ma la classe derivata non ESTENDEVA le funzioni di
quella padre?
questo discorso vale solo per le funzioni con lo stesso NOME? e perché
non per quelle con lo stesso nome E parametri?


 non per quelle con lo stesso nome E parametri?
La classe derivata eredita i nomi presenti nello scope della classe base
e può aggiungerne di nuovi, ma se definisce qualche cosa con un nome già
presente nella classe base tutte le signature legate a quel nome nella
classe base vengono nascoste. Se la signature (quindi non solo il nome,
ma anche i tipi) è presente nella classe base come funzione virtuale
allora la nuova funzione ridefinisce quella della classe base.
struct B {
    void a(int);
    void a(long);
    void b(int);
    void b(long);
    void c(int);
    void c(long);
    virtual void d(int);
    virtual void d(long);
};
struct D: public B {
    void b(int);
    void c(float);
    void d(int);
};
nello scope D::
a è in overload fra B::a(int) e B::a(long)
b corrisponde a D::b(int), sia B::b(int) che B::b(long) sono nascoste
c corrisponde a D::c(float), sia B::c(int) che B::c(long) sono nascoste
d corrisponde a D::d(int) che è l'override di B::d(int), B::d(long) è
nascosta


 nascosta
Non mi e' chiara la differenza tra b e d.
All'atto pratico cosa cambia tra avere l'override di B::d(int) ed avere
B::c(int) nascosta?
--
Gerolamo

 wrote in message
news:GCDz7.44994$1H1.5...@news.infostrada.it...

Se la chiamata la fai nello scope D:: di un oggetto di tipo D non cambia
nulla. Ma se la fai nello scope B:: di un oggetto di tipo D (o nello
scope D:: di un oggetto derivato da D che fa anch'esso l'override) la
differenza c'e'.
Pensaci.


 Pensaci.
ci ho provato... un aiutino??? :-))
--
Gerolamo

     D erede;
      B &rerede = erede;
e le chiamate a
 re.foo();
 erede.foo();
 erede.bar();
 rerede.foo();
e vedere cosa esce.
Poi se ti va puoi anche derivare una classe E da D che fa l'override di
d(int) e riprovare da capo aggiungendo:
E hehe;
D &dhehe=hehe;
B &bhehe=hehe;
e le varie chiamate.


  rerede.foo();
questa da lo stesso risultato della seconda
sono B::b(int)
sono B::b(long)
sono D::d(int)
sono B::d(long)
"rerede" si comporta come "erede", cioe' come se fosse di tipo D.
a questo punto mi si sta looppando il cervello,
ma non ho ancora colto la differenza... :-(
(sono un po' fuori forma, eh?)
Intanto grazie per l'aiuto (ma ne avro' ancora bisogno...)
--
Gerolamo

 ma non ho ancora colto la differenza... :-(
Le differenza è proprio quella. rerede si comporta come erede. Solo che
nel caso di erede tu stai chiamando un metodo della classe B in un
oggetto che tu sai essere di tipo D, quindi è naturale aspettarsi che la
terza chiamata sia a D::d(int). Ma nel caso di rerede tu stai facendo
una chiamata ad una reference a B e potresti non sapere assolutamente
nulla di D. Prova a immaginare una situazione come questa:
// file B.hpp
... dichiari class B
// file B.cpp
#include <iostream>
#include "B.hpp"
... implementi class B
// file pippo.hpp
#include "B.hpp"
void pippo(B&b);
// file pippo.cpp
#include "pippo.hpp"
void pippo(B&b)
{
    b.foo();
}
// file D.hpp
#include "B.hpp"
... dichiari class D
// file D.cpp
#include <iostream>
#include "D.hpp"
... implementi class D
// file main.cpp
#include "B.hpp"
int main()
{
    B b;
    D d;
    pippo(b);
    pippo(d);
}
Ora concentrati sul file pippo.cpp
Tutto quello che vede è la dichiarazione di B e della funzione pippo che
implementa.
Questo file non sa nulla della classe D. Per lui la classe D non esiste.
Si potrebbe dire che richiama in metodo foo di B e che questo metodo
potrebbe conoscede D. Ma se guardi il file B.cpp ti accorgi che il
metodo B::foo a sua volta non sa assolutamente nulla di D. D non esiste
ne nel codice di pippo ne nel codice da esso richiamato direttamente o
indirettamente. Quindi si potrebbe dedurre che pippo si comporti sempre
allo stesso modo. Eppure la seconda chiamata del main ti dimostra che
pippo non si comporta sempre allo stesso modo. Proprio perchè c'è di
mezzo una funzione virutale.
rerede.foo() dovrebbe comportarsi come re.foo() invece si comporta come
erede.foo(). In erede la foo e la bar contengono lo stesso codice ma si
comportano diversamente pur essendo chiamate dallo stesso oggetto.
Proprio perchè le quattro chiamate (identiche) avvengono in scope di
chiamata diversi.


 chiamata diversi.
ok
Ti ringrazio per le spiegazioni!
--
Gerolamo