PDA

Visualizza la versione completa : [C++] operatori equals e instanceof: esistono? Alternative?


fbcyborg
16-12-2011, 17:22
Salve gente,

come molti avranno intuito dal titolo, sto piano piano passando da Java a C++, e volendo realizzare un piccolo software che ho fatto in Java, anche in C++, mi trovo di fronte ad alcuni problemini.

Per prima cosa vorrei capire bene come verificare se due oggetti sono uguali. In Java esiste l'operatore equals, che pu essere ridefinito, ad esempio come segue:


public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof ClasseDellOggetto))
return false;
ClasseDellOggetto o1 = (ClasseDellOggetto) o;
return this.campo1==o1.campo1 && this.campo2==o1.campo2;
}
Ovviamente la classe ClasseDellOggetto, presa in esempio, qui ha due attributi.

Vorrei sapere se c' un metodo "standard" in C++ per fare la stessa cosa. Ho letto qua e la, che basterebbe verificare se tutti gli attributi di un oggetto sono uguali a quelli di un altro per verificare se sono uguali: corretto? O c' dell'altro?

Dal problema dell'equals, scaturisce il problema istanceof: esiste l'analogo in C++?
Come si fa a vedere se un certo oggetto istanza di una certa classe?

EDIT:
per il momento mi sono limitato a definire una funzione del genere per vedere se due oggetti sono uguali (ovvero se i loro attributi sono uguali):

bool MyClass::equals(MyClass *p){
if(p==NULL)
return false;
return (this->attr1==p->attr1 &&
this->attr2==p->attr2);
}

Pare che funzioni, spero sia corretto come ho fatto.

shodan
16-12-2011, 18:32
Per il primo caso puoi usare operator==(), ma funziona solo con oggetti non con puntatori a oggetti (in questo caso viene confrontato l'indirizzo).


class Qualcosa {
public:
bool operator==(const Qualcosa& q) {
return dt == q.dt;
}
private:
int dt;
};

Qualcosa a,b;
if (a == b) { azione; }



Per il secondo puoi vedere typeinfo
http://www.cplusplus.com/reference/std/typeinfo/type_info/
la cui implementazine per dipende dal compilatore.

fbcyborg
16-12-2011, 18:39
Molte grazie, quindi basta ridefinire l'operatore == in pratica.

fbcyborg
16-12-2011, 20:52
Originariamente inviato da shodan


Qualcosa a,b;
if (a == b) { azione; }


Una domanda: ho provato a fare l'override dell'operatore ==. Perch se provo a farlo su due puntatori a oggetto (o meglio con due oggetti creati con la "new") non funziona? Mi restituisce sempre "diversi".



Oggetto *o1 = new Oggetto("ciao");
Oggetto *o2 = new Oggetto("ciao");

if(o1 == o2){
cout << "Uguali" << endl;
}else{
cout << "Diversi" << endl;
}

O meglio: c' un altro modo per farlo?
Posso immaginare che o1 e o2 puntano a indirizzi di memoria diversi, quindi l'uguale mi dovrebbe dare sempre un valore falso, ma pensavo che ridefinendo quell'operatore la cosa funzionasse lo stesso.

La funzione che ho scritto di questo tipo:



bool Oggetto::operator==(const Oggetto& o){
return (this->arg1==o.arg1 &&
this->arg2==o.arg2);
}

shodan
16-12-2011, 21:35
Overload. L'override lo hai solo col polimorfismo.


funziona solo con oggetti, non con puntatori a oggetti (in questo caso viene confrontato l'indirizzo).

Nella pratica si definisce una funzione come hai fatto tu e si usa l'operatore==() per richiamarla.
In questo caso si definisce l'operatore inline (o nel corpo della classe) in modo che il compilatore possa ottimizzare la chiamata.
In due parole: zucchero sintattico.

fbcyborg
16-12-2011, 21:44
Perdonami, l'avevo anche letto che funzionava solo con oggetti. La fretta mi ha fatto confondere.

Nella pratica si definisce una funzione come hai fatto tu e si usa l'operatore==() per richiamarla.

Quindi sostanzialmente dovrei fare una cosa del genere?


inline bool MyClass::operator==(const MyClass *p){
if(p==NULL)
return false;
return (this->attr1==p->attr1 &&
this->attr2==p->attr2);
}

shodan
16-12-2011, 22:19
Quasi.


class Qualcosa {
public:
bool operator==(const Qualcosa& q) {
return this->equals(q);
}

bool equals(const Qualcosa& q) {
return this->equals(&q);
}

bool equals(const Qualcosa* q) {
return dt == q->dt;
}

private:
int dt;
};

Qualcosa a,b;
Qualcosa *pa, *pb;

pa = &a;
pb = &b;

if (a == b) { azione; } // corretto (*)

if ( (*pa) == b ) { ... } // corretto;

if ( (*pa) == (*pb) ) { ... } // corretto;

if ( pa->equals(*pb) ) { ... } // corretto;

if ( a.equals(b) ) { ... } // corretto


Se metti in overload equals() per far accettare un puntatore, supporti in pratica tutte le sintassi possibili.



if (pa->equals(pb)) ...
if (pa->equals(b)) ...

etc.
(*) questa la sintassi naturale, obbligatoria per lavorare con gli algoritmi standard.

fbcyborg
16-12-2011, 22:31
Grazie infinite!!!

:) :)

MacApp
17-12-2011, 03:49
Originariamente inviato da fbcyborg

public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof ClasseDellOggetto))
return false;
ClasseDellOggetto o1 = (ClasseDellOggetto) o;
return this.campo1==o1.campo1 && this.campo2==o1.campo2;
}

stai cercando di scrivere codice "offuscato"? Ti rendi conto che l'identificatore "o" poco leggibile?
http://en.wikipedia.org/wiki/Obfuscated_code

identificatore NON offuscato (autodocumentante):
applicationShouldTerminateAfterLastWindowClosed (http://developer.apple.com/library/mac/#documentation/cocoa/Reference/NSApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40008592-CH1-SW9)

Loading