Newsgroup: it.comp.lang.c++
Titolo: Classe astratta e operatori relazionali

Salve a tutti,
diciamo di avere una classe base
class Base {
public:
  ...
  virtual int getUniqueId() const = 0;
  bool operator <  (const Base & other) const { return getUniqueId() <
other.getUniqueId(); }
  ...
};
dove getUniqueId restituisce un valore unico per ogni oggetto distinto
di ogni sottoclasse.
Le classi derivate reimplementano getUniqueId() (ovviamente) ma non
l'operatore relazionale.
Ora: ha compilato e sembra funzionare, ho creato due oggetti di due
classi derivate diverse, e l'operatore < sembra andare, qualcosa del
genere
Base* d1 = new Deriv1();
Base* d2 = new Deriv2();
bool b = d1 < d2;   // da' il valore giusto
ma non capisco perche': come puo' accettare come argomento un oggetto
Base, quando Base non puo' essere istanziata?
Thx,
Pleg

 Base, quando Base non puo' essere istanziata?
La funzione operator<() non accetta un oggetto Base come argomento, ma 
un riferimento ad un oggetto Base. Quando si maneggiano oggetti 
polimorfi attraverso riferimenti e puntatori il programma tiene traccia 
del tipo effettivo e quindi può risolvere le chiamate alle funzioni 
membro correttamente.
Tutto questo è valido ma _NON_ è quello che stai facendo tu con 
l'operatore di confronto nella riga:
bool b = d1 < d2;
Se ti da la risposta corretta è solo una coincidenza, perché quella 
istruzione compara gli indirizzi contenuti nei due puntatori, non chiama 
affatto le funzioni getUniqueId().
Puoi verificare questa cosa aggiungendo una istruzione di output nelle 
funzioni getUniqueId() che definisci dentro Deriv1() e Deriv2(), nota la 
differenza di output delle due operazioni di confronto dentro main() nel 
codice seguente (ho incluso anche l'output prodotto sul mio computer):
//-------
#include <iostream>
using namespace std;
class Base {
public:
     virtual int getID() const = 0;
     bool operator<(const Base& other) const {
         return getID() < other.getID();
     }
protected:
     static int instances_count;
};
int Base::instances_count = 0;
class Deriv1 : public Base {
public:
     Deriv1() : id(--instances_count) {}
     int getID() const {
         cout << "Deriv1::id == " << id << endl;
         return id;
     }
private:
     int id;
};
class Deriv2 : public Base {
public:
     Deriv2() : id(--instances_count) {}
     int getID() const {
         cout << "Deriv2::id == " << id << endl;
         return id;
     }
private:
     int id;
};
int main() {
     Base* d1 = new Deriv1;
     Base* d2 = new Deriv2;
     cout << boolalpha << endl;
     cout << "d1 == " << d1 << endl;
     cout << "d2 == " << d2 << endl;
     bool ptrs_comp = d1 < d2;
     cout << "ptrs_comp == " << ptrs_comp << endl;
     cout << endl;
     bool ids_comp = (*d1) < (*d2);
     cout << "ids_comp == " << ids_comp << endl;
     return 0;
}
/*
output:
d1 == 0x962b08
d2 == 0x962b28
ptrs_comp == true
Deriv1::id == -1
Deriv2::id == -2
ids_comp == false
*/
//-------
-- 
  FSC - 
http://userscripts.org/scripts/show/59948
 
http://fscode.altervista.org
 - 
http://sardinias.com

 bool b = d1 < d2;
In realta' nel programma facevo proprio
bool b = *d1 < *d2;
e mi son perso la dereferenziazione mentre ho scritto qui ^_^;
Pleg

 e mi son perso la dereferenziazione mentre ho scritto qui ^_^;
Cose che capitano :-)


 ché c'è gente alquanto permalosa ;-)
Sono 12 anni che scrivo su usenet ma questa non l'avevo mai sentita!
Che cosa sono le "righe di attribuzione" ??  L"unico significato che
conosco sono le linee delle licenze in testa al codice, ma non mi pare
sia questo il caso...
Cmq, credo che sia meglio tenere solo il minimo indispensabile a
capire la risposta, altrimenti ogni messaggio dovrebbe contenere tutti
i precedenti e i messaggi diventerebbero faticosi da leggere. E se uno
vuole leggere il codice, lo trova nel messaggio precedente (ci pensa
google :)
Pleg

, on 12/08/2010 08:32:05, wrote:
Urca, mai fatto caso se le tagliavo o no quando tagliavo il resto del
messaggio, e nessuno si e' mai lamentato :)
Pleg

 google :)
Sono d'accordo con te sul fatto di tagliare fino al minimo, ma le righe 
di attribuzione fanno parte di quel minimo indispensabile.
Poi scusa, chi ti dice che tutti accedano a USENET tramite google?
Non voglio azzardare statistiche ma credo che la maggior parte degli 
utenti di USENET usino dei newsreader più decenti del pessimo Google Groups.




Passa a fare lo stesso su qualche gruppo tecnico in lingua inglese e poi 
vedi... ;-)
