Newsgroup: it.comp.lang.c++
Titolo: Sull'ereditarietà...

Ciao a tutti!
ho un problemino sull'uso dell'eredità...
se eredito una classe definita come:
//-------------
class Base {
    public:
        ...
        pippo();
        ...
    private:
        ...
};
//-------------
in una classe del tipo:
//-------------
class Deriv : public Base {
    ...
};
//-------------
dovrei teoricamente poter fare cose del tipo:
        Deriv pluto;
        pluto.pippo();
giusto?
Invece se lo faccio  il compilatore si lamenta di non trovare la funzione
pippo()
Perchè? Non dovrei ereditare anche i membri pubblici? Un oggetto Deriv non
dovrebbe poter essere usato come se fosse del tipo Base?
Daniele

class Base {
    public:
        void pippo();
};
class Deriv : public Base {
};
void Base::pippo() {
}
int main() {
        Deriv pluto;
        pluto.pippo();
}
Questo funziona. Non e' che ti sei dimenticato di *definire* Base::pippo() ?
Ciao,
Nicola
P.S. La prossima volta posta un esempio completo.

#ifndef TIME_H
#define TIME_H
class Time {
   public:
      Time ( int h=0, int m=0 ) { set ( h, m ); };
      void set ( int h, int m );
      void prnt ();
      int getH () { return hour; };
      int getM () { return min; };
   protected:
      int hour, min;
};
#endif
#ifndef OROLOGIOBASE_H
#define OROLOGIOBASE_H
#include "time.h"
class OrologioBase : public Time {
   public:
   OrologioBase ( int h=0, int m=0 ) :Time ( h, m ) {};
   void set ( Time );
   void add ( int m );
   void subtract(int m ) { add (-m); };
   void tick () { add (1); };    // adds a minute
   Time show();
};
#endif
int main ()
{
OrologioBase clk1;
cout << "def clock created..." << endl;
clk1.show();
clk1.set( 23, 55 );
clk1.show();
  system ("PAUSE");
  return 0;
}
-------------------------------------------
33 D:\Univ\POC\Exercises\testClock.cpp
no matching function for call to `OrologioBase::set (int, int)'
11 D:\Univ\POC\Exercises\OrologioBase.h
candidates are: void OrologioBase::set(Time)
-------------------------------------------
vedi? come se ereditasse solo i dati e non i metodi

Seondo me, dimentichi una cosa importante.....
virtual Time::Set(....)
se non è virtual, la funzione della classe base non sarà chiamata dalla
ereditate. Visto che nella ereditata ne hai definito una identica (set...)
sarà chiamata quest'ultima.
Puoi, ma non credo che sia questo il tuo scopo invocare esplicitamente
Time::set(.....) dalla classe ereditata.
Saluti,
Sal
"** !! GnaSKuRu !! **" <gnask...@SPAMlibero.it> ha scritto nel messaggio
news:EOnM9.32051$TC5.9...@twister1.libero.it...


 ha scritto nel messaggio
news:att252$rpm$1...@lacerta.tiscalinet.it...


 compilatore....
Le funzioni le ho definite, ma nn le ho postate x non appesantire il post,
ho provato con virtual, ma è la stessa cosa,
che sia il Dev-C++? (improbalile)
Dan

 vedi? come se ereditasse solo i dati e non i metodi
Scusami, ma le due dichiarazioni di set sono diverse, per cui quella nella
classe derivata MASCHERA quella della classe superiore.
Se la funzione fosse stata dichiarata nell'ancestor come virtuale,
probabilmente avresti avuto un warning, ma così si tratta solo di introdurre
un nuovo simbolo nell'ambiente che viene introdotto dalla dichiarazione
della classe.
E' un po' come:
{
    double i = 5.0;
    {
        int i = 6;
        std::cout << i << std::endl;
    }
}
Nessuno ti restituisce un warning perché mascheri la double i, ma è proprio
quello che fai.
    Rony

che sia il Dev-C++? (improbalile)
I dubbi sul compilatore sono gli ultimi che ti devono
venire.
Quello che hai scoperto e' il terribile "hiding":
se una classe derivata definisce un metodo con
un certo nome allora tutti i metodi con quel nome
delle classi base vengono "nascosti". Es:
 class Base
 {
   public:
     void foo(int) { }
 };
 class Derived : public Base
 {
   public:
     void foo(int,int) { }
 };
 class Derived2 : public Base
 {
   private:
     double foo() { return 3.14; }
 };
 class Derived3 : public Base
 {
   public:
     int foo() { return 314; }
     void foo(int x) { Base::foo(x); }
 };
 class Derived4 : public Base
 {
   public:
     int foo() { return 314; }
     using Base::foo;
 };
 int main()
 {
   Base b;
   Derived d;
   Derived2 d2;
   Derived3 d3;
   Derived4 d4;
   b.foo(1);       // Ok
   //d.foo(1);     // Errore: foo(int) e' nascosta
   d.Base::foo(1); // Ok, qualifica esplicita
   //d2.foo();     // Errore: e' private
   //d2.foo(1);    // Errore: foo(int) nascosta (da una private)
   d3.foo(1);      // Ok. Redirezione.
   d4.foo(1);      // Ok. Nome importato con using.
 }
Una cosa che a suo tempo mi ha colpito in modo
particolare era il caso di d2: aggiungere una
funzione *private* puo' in C++ fare in modo che
codice che prima compilava non sia piu' compilabile.
Andrea