PDA

View Full Version : Uguaglianza tra oggetti


misterx
11-07-2007, 07:19
ho riscoperto l'acqua calda però mi interessa sapere qualcosina di più.

Ho istanziato due oggetti di tipo Memo contenenti a volte le medesime stringhe ed a volte stringhe differenti.
Per la caratteristica di essere oggetti, sono confrontabili tra loro con l'operatore di uguaglianza ma......come viene verificata l'uguaglianza dei due oggetti ?????

mad_hhatter
11-07-2007, 09:04
spero di aver capito bene la domanda...

nota che ti parlo di come funziona la cosa in Java. In Java hai 2 operatori di uguaglianza tra oggetti: "==" e "equals".

il primo confronta L'INDIRIZZO di due riferimenti a oggetti:
Class1 c1 = new Class1();
Class1 c2 = new Class1();

-> c1 == c2 è FALSE

se ora faccio c2 = c1, allora le due variabili puntano allo stesso oggetto e di conseguenza c1 == c2 è, ora, TRUE

passiamo ora al secondo operatore, equals.
supponiamo che Class1 abbia due membri, per semplicità di tipo primitivo e contenga un metodo equals definito come segue:
Class1 {
int m1;
double m2;
...

public boolean equals(Class1 c) {
return (this.m1 == c.m1) && (this.m2 == c.m2);
}
}

ora,
Class1 c1 = new Class1();
Class1 c2 = new Class1();

c1.equals(c2) è TRUE

la cosa importante e interessante è che equals è completamente personalizzato, quindi sei tu a decidere qual è il criterio di uguaglianza

misterx
11-07-2007, 10:14
hai capito cosa intendo :)

Ma supponi di avere istanziato due oggetti di tipo stringa, se sono oggetti puoi scrivere

s1 != s2 o s1 == s2

mi chiedevo il funzionamento interno del confronto e cioè, se attraverso l'operaotre '=' usato su due oggetti, veniva scandito il contenuto delle due stringhe per rotirnare che i due oggetti sono uguali.

Posso istanziare due rettangoli con la stessa classe e delle stesse dimensioni ma posso dire credo, di avere due rettangoli uguali ma due oggetti diversi!

mad_hhatter
11-07-2007, 11:36
infatti l'operatore "==" è logico, mentre "equals" è SEMANTICO

se tu hai due stringhe che rappresentano la stessa sequenza di caratteri, o due rettangoli aventi uguale altezza e uguale larghezza, essi sono semanticamente uguali, ma possono essere oggetti diversi.

se tu fai:

String s1 = "abc";
String s2 = "abc";

allora s1 == s2 è false, ma s1.equals(s2) è true perchè il secondo è implementato per confrontare la sequenza di caratteri, mentre il primo guarda solo l'indirizzo contenuto nei riferimenti.

Lo stesso dicasi per i rettangoli.
E' per questo che esiste "==" E ANCHE "equals".

In C++, ad esempio, con l'overloading degli operatori potresti, FORSE (perchè non conosco il C++), fare in modo che "==" si comporti come "equals".

andbin
11-07-2007, 11:40
se tu fai:

String s1 = "abc";
String s2 = "abc";

allora s1 == s2 è falseBeh no, in questo caso specifico (assegnazione di una stringa literal uguale), s1 == s2 dà true. La stringa literal è la stessa e nel constant pool ce n'è una sola. Pertanto i reference sono uguali.


String s1 = new String ("abc");
String s2 = new String ("abc");

Qui s1 == s2 è sempre in ogni caso false.

misterx
11-07-2007, 12:17
in Borland Builder C++

String s1= "abc";
String s2= "abc";

is1 == s2 ???? "vero"

String s1= "abc";
String s2= "abcd";

is1 == s2 ???? "falso"

mattia.pascal
11-07-2007, 13:30
Parlando di OOP quando si scrive una nuova classe si deve sempre fare l'override del metodo equals in quanto è l'unico metodo per testare l'uquaglianza (semantica) tra due oggetti. Poi che in Java l'operatore "==" fatto su due oggetti stringa uguali restituisca true è solo una scelta fatta dalla Sun.

mapomapo
11-07-2007, 13:37
in c++ se fai l'include di <string> o <cstring> ora non ricordo bene hai già una classe nella quale è overloadato l'operatore == per effettuare una strcmp....

per quel che riguarda gli oggetti -sempre in c++- ti consiglio di fare un overloading dell'operatore == per fargli fare ciò che ti serve....

Vito

misterx
11-07-2007, 19:28
uhm.....ci siamo leggermente persi

Ho due oggetti di tipo memo quindi due istanze di tali oggetti.
Se scrivo Memo1->Text != Memo2->Text dovrei ottenere true se entrambi gli oggetti sono dello stesso tipo ed hanno i medesimi attributi o proprietà, indifferentemente dall'indirizzamento in memoria

aik
11-07-2007, 20:22
Che linguaggio usi?


di solito nei linguaggi che non ammettono un uso diretto dei puntatori ci sono queste due scelte perchè deve comunque essere possibile fare entrambi i confronti (java):
per sapere se due oggetti sono il solito:
==

per sapere se due oggetti hanno lo stesso contenuto:
equals

Nei linguaggi dove puoi usare direttamente i puntatori (c++)
per sapere se due stringhe sono il solito oggetto:
&obj1 == &obj2

per sapere se due oggetti hanno lo stesso contenuto:
obj1 == obj2 (se fanno l'overriding dell'operatore ==)

più facile di così

se ho detto qualche cazzata correggetemi :D

misterx
11-07-2007, 21:18
parlo di C++ ma in termine di oggetti non credo ci sia molta differenza tra C++ e java, sbaglio ?

Se scrivo Memo1 == Memo2 mi viene restituito un false in quanto con molta probabilità entra in gioco l'indirizzamento in memoria, oggetti dello stesso tipo ma che vengono riconosciuti come individui a se.

Se navigo al loro interno con la notazione -> ed arrivo a Text che è il loro contenuto, tale contenuto mi ritorna un true se entrambi contengono il medesimo testo, indifferentemente dalla lunghezza di quest'ultimo.

La mia domanda era appunto: quando scrivo Memo1->Text == Memo2->Text cosa fa il codice celato in quel '==' per scoprire che i due contenuti dei Memo sono uguali ?

PGI-Bis
11-07-2007, 21:57
Gli oggetti C++ e gli oggetti Java non sono neanche lontani parenti :D.

Le specifiche di C++ (ISO '98) ci dicono che il risultato della comparazione per uguaglianza di due puntatori ad oggetti dello stesso tipo è true se e solo se entrambi sono null, puntano allo stesso oggetto o al componente di un array successivo all'ultimo.

misterx
12-07-2007, 05:56
parlando esclusivamente di oggetti non penso che un oggetto C++ sia differente da un oggetto java

PGI-Bis
12-07-2007, 11:22
Se parliamo di bit in memoria, sono entrambi collezioni di uno e zero ma l'oggetto, in quanto definizione di un'identità, in Java è più "cicciotto". Il minimo oggetto Java è l'unione della definizione di java.lang.Object e qualcos'altro. Quello che c'è scritto in Object è parecchio ma due cose risaltano più di tutte. La prima è la definizione di identità: equals e hashCode. La seconda è l'introspezione: getClass. Non è poco.

misterx
12-07-2007, 17:05
intendevo a livello concettuale e non implementativo.
Però ancora nessuno mi ha risposto come funziona quel == tra due oggetti :(

aik
13-07-2007, 08:39
Veramente te lo hanno spiegato tutti :D

misterx
13-07-2007, 09:25
Veramente te lo hanno spiegato tutti :D

mi sa che hai letto male!

Ed_Bunker
13-07-2007, 09:25
Ma sbaglio o in C++ e' anche possibile sovrascrivere l'operatore di uguaglianza == ?

In java, invece, nel caso di oggetti, non dovrebbe corrispondere a chiamare il metodo equals ?

andbin
13-07-2007, 10:06
Ma sbaglio o in C++ e' anche possibile sovrascrivere l'operatore di uguaglianza == ?Sì, è possibile (è quello che viene fatto ad esempio nella classe std::string).

In java, invece, nel caso di oggetti, non dovrebbe corrispondere a chiamare il metodo equals ?In Java l'operatore == applicato a due operandi di tipo reference effettua solo una comparazione sui valori dei reference, non sul contenuto degli oggetti.

mad_hhatter
13-07-2007, 14:30
intendevo a livello concettuale e non implementativo.
Però ancora nessuno mi ha risposto come funziona quel == tra due oggetti :(

boh, mi pareva abbastanza chiaro dalle risposte, forse non ho capito cosa chiedi... comuqnue in Java "==" confronta gli indirizzi di memoria a cui puntano i riferimenti ai 2 oggetti. Ogni riferimento del tipo "Class c;" corrisponde a una word contenente l'indirizzo di memoria dove si trova fisicamente l'oggetto...

più di così non so cosa risponderti... mi spiace

misterx
13-07-2007, 14:42
boh, mi pareva abbastanza chiaro dalle risposte, forse non ho capito cosa chiedi... comuqnue in Java "==" confronta gli indirizzi di memoria a cui puntano i riferimenti ai 2 oggetti. Ogni riferimento del tipo "Class c;" corrisponde a una word contenente l'indirizzo di memoria dove si trova fisicamente l'oggetto...

più di così non so cosa risponderti... mi spiace

non è solo una uestione di indirizzi.
E' chiaro che se confronto due riferimenti ad oggetti come hai scritto tu mi viene risposto che non sono uguali in quanto puntano ad aree di memoria differenti, hanno indirizzi diversi.

Se scrivo in C:

char stringa1[]="abcde";
char stringa2[]="abcde";

non posso poi anche scrivere banalmente

if(stringa1 == stringa2)
printf("le stringhe sono uguali");

ma devo usare una funziona appropriata, la strcmp() se non ricordo male.

Questo discorso non vale più se si parla di programmazione ad oggetti; nella OOP posso scrivere stringa1 == stringa2 e mi viene restituito il risultato corretto.
Come avviene nella realtà la comparazione tra le due stringhe in OOP ?
Come per il normale linguaggio C ?

Quello che chiedevo era come funziona l'implementazione interna in OOP dell'uguaglianza.

Spero di essere stato più chiaro ora :)

mad_hhatter
13-07-2007, 14:59
non è solo una uestione di indirizzi.
E' chiaro che se confronto due riferimenti ad oggetti come hai scritto tu mi viene risposto che non sono uguali in quanto puntano ad aree di memoria differenti, hanno indirizzi diversi.

Se scrivo in C:

char stringa1[]="abcde";
char stringa2[]="abcde";

non posso poi anche scrivere banalmente

if(stringa1 == stringa2)
printf("le stringhe sono uguali");

ma devo usare una funziona appropriata, la strcmp() se non ricordo male.

Questo discorso non vale più se si parla di programmazione ad oggetti; nella OOP posso scrivere stringa1 == stringa2 e mi viene restituito il risultato corretto.
Come avviene nella realtà la comparazione tra le due stringhe in OOP ?
Come per il normale linguaggio C ?

Quello che chiedevo era come funziona l'implementazione interna in OOP dell'uguaglianza.

Spero di essere stato più chiaro ora :)

ma guarda che fin'ora abbiamo sempre e solo parlato di OOP ! io infatti ti ho sempre parlato di Java... è difficile parlare di OOp in generale perché ogni linguaggio ha le sue peculiarità, ma in generale esiste un operatore di uguaglianza "fisica" (che controlla il valore del riferimento) e in Java è "==" e un operatore "semantico" (in Java "equals") che va personalizzato per ogni classe e che, per le stringhe fa il confronto guardando se 2 stringhe contengono i medesimi caratteri nelle medesime posizioni...

lo so, sto continuando a ripetermi, ma più di così non so che dire :)

PGI-Bis
13-07-2007, 15:31
Da un punto di vista teorico, cioè nell'orientamento agli oggetti in quanto prospettiva, il concetto di uguaglianza non esiste. Esiste l'identità ma è tutt'altra cosa ed è solitamente implicita o simbolica.

misterx
13-07-2007, 17:18
ma guarda che fin'ora abbiamo sempre e solo parlato di OOP ! io infatti ti ho sempre parlato di Java... è difficile parlare di OOp in generale perché ogni linguaggio ha le sue peculiarità, ma in generale esiste un operatore di uguaglianza "fisica" (che controlla il valore del riferimento) e in Java è "==" e un operatore "semantico" (in Java "equals") che va personalizzato per ogni classe e che, per le stringhe fa il confronto guardando se 2 stringhe contengono i medesimi caratteri nelle medesime posizioni...

lo so, sto continuando a ripetermi, ma più di così non so che dire :)

grazie lo stesso, ci arriverò per altre strade :)

misterx
13-07-2007, 17:29
grazie lo stesso, ci arriverò per altre strade :)

anzi, prima di arrenedermi....


Image1->Picture == Image2->Picture;

In ambiente Borland C++ è possibile scrivere una cosa del genere e tale costrutto ti restituisce se due immagini sono uguali oppure si differiscono anche di un solo pixel.

So bene anch'io che per ogni oggetto/classe/componente quel == viene riscritto appositamente per il tipo di oggetto che si sta confrontando; quello per le stringhe non viene certo usato per confrontare immagini o altro; chidevo quindi come diamine funzionava quell' == per le stringhe :)

Questa era la domanda, in origine, che facevo.

Mi sarebbe bastato una risposta del tipo:
di sicuro esiste un ciclo for, un luogo di quell' ==, che confronta un carattere alla volta e se le due stringhe sono uguali, ti viene ritornato true.

Più di così non so come chiedere.

mad_hhatter
13-07-2007, 17:54
Mi sarebbe bastato una risposta del tipo:
di sicuro esiste un ciclo for, un luogo di quell' ==, che confronta un carattere alla volta e se le due stringhe sono uguali, ti viene ritornato true.

esiste un altro modo "generico" altrettanto naturale di testare l'uguaglianza del contenuto di due stringhe?

se l'uguaglianza del contenuto di due stringhe è definita come il fatto che le due stringhe siano formate dalla stessa sequenza di caratteri, mi pare abbastanza ovvio che il test verrà fatto con un ciclo che testa l'uguaglianza di 2 caratteri corrispondenti nelle due stringhe... al limite, l'unica cosa da aggiungere è che prima di intraprendere il ciclo è probabile che venga testata l'uguaglianza per indirizzo, ma il resto mi pare assolutamete ovvio...

mad_hhatter
13-07-2007, 17:55
anzi, prima di arrenedermi....


Image1->Picture == Image2->Picture;

In ambiente Borland C++ è possibile scrivere una cosa del genere e tale costrutto ti restituisce se due immagini sono uguali oppure si differiscono anche di un solo pixel.



questo dipende dalle semantiche degli operatori di uno specifico linguaggio... in Java ad esempio non è così...

boh, io continuo a non capire la domanda

misterx
13-07-2007, 19:45
questo dipende dalle semantiche degli operatori di uno specifico linguaggio... in Java ad esempio non è così...

boh, io continuo a non capire la domanda

se provi ad usare qualche componente di terze parti capisci la mia domanda.

mad_hhatter
14-07-2007, 12:26
se provi ad usare qualche componente di terze parti capisci la mia domanda.

ma stringhe non sono componenti di terze parti... e comunque gli operatori di uguaglianza, a meno che non sia possibile farne l'overloading, hanno un comportamento ben preciso...

poi e' ovvio che un componente di terze parti fa quello che gli pare... se chi ha implementato l'overloading dell'operatore di uguaglianza ha deciso di fare cose strane non lo puoi sapere a meno di non avere i sorgenti, decompilare, leggere l'eventuale documentazione...

che tu voglia capire cosa fa internamente un componente sviluppato da altri lo capisco benissimo, mi pongo la stessa domanda in continuazione... che tu chieda come funziona la comparazione di stringhe mi appare meno ovvio, soprattutto dopo le nostre risposte... ma forse sono io che continuo a non capire il background della tua domanda

misterx
14-07-2007, 12:44
ma stringhe non sono componenti di terze parti... e comunque gli operatori di uguaglianza, a meno che non sia possibile farne l'overloading, hanno un comportamento ben preciso...

poi e' ovvio che un componente di terze parti fa quello che gli pare... se chi ha implementato l'overloading dell'operatore di uguaglianza ha deciso di fare cose strane non lo puoi sapere a meno di non avere i sorgenti, decompilare, leggere l'eventuale documentazione...

che tu voglia capire cosa fa internamente un componente sviluppato da altri lo capisco benissimo, mi pongo la stessa domanda in continuazione... che tu chieda come funziona la comparazione di stringhe mi appare meno ovvio, soprattutto dopo le nostre risposte... ma forse sono io che continuo a non capire il background della tua domanda


da come mi hai risposto ora mi pare che tu abbia capito benissimo il mio dubbio!
Non c'è un background da capire, dovevo solo giustificarmi il fatto che scrivere RichEdit1->Text == RichEdit2->Text fosse una cosa corretta e non un risultato casuale usando l'operatore == tra componenti.
La documentazione che ho a disposizione non è motlo chiara sotto a questo punto di vista.
Mi bastava anche, che uno più navigato di me sull'uso dei componenti mi avesse risposto affermativamente che scrivere == come ho fatto io è corretto.

Per me un componente rimane una scatola nera nella quale non posso vedere il suo funzionamento interno.

Quello che tu definisci overloading, non è che nel mio caso è overriding ?
Nel mio caso non ho sviluppato alcuna classe ma sto usando componenti = scatole nere.

mad_hhatter
14-07-2007, 13:00
Quello che tu definisci overloading, non è che nel mio caso è overriding ?
Nel mio caso non ho sviluppato alcuna classe ma sto usando componenti = scatole nere.

dipende (tanto per cambiare :D )

il fatto che "==" sia polimorfico e' overloading... se chi ha scritto il componente doveva implementare l'uguaglianza del contenuto di due stringhe E ha RIDEFINITO l'operatore "==" per le stringhe E tale operatore era gia' definito per operare su stringhe ALLORA siamo in presenza di overriding.

e' identico a quello che succede per qualsiasi metodo:
se eriditi un metodo method(int) e crei un metodo method(double) e' overloading, ma se ridefinisci method(int) e' overriding, come ben sai... bene, nei linguaggi che permettono l'overloading degli operatori funziona uguale (ammesso e non concesso, perche' non conosco tali linguaggi, che sia possibile anche fare l'overriding degli operatori... se cio' non fosse possibile e se RichEdit.Text fosse una String allora avresti la certezza che == tra stringhe e' l'operatore di confronto standard del tuo linguaggio e non dovresti preoccuparti di cosa ha fatto lo sviluppatore del componente... ma ci sono troppi "SE" :) )

mad_hhatter
14-07-2007, 13:04
in ogni caso per fugare ogni dubbio basta fare un paio di esperimenti... alla fine stiamo parlando di una sequenza finita di istruzioni che difficilmente lancia thread (parlo del confronto tra stringhe): provi a fare

RichText1->Text = new String("abc");
RichText2->Text = new String("abc");

confronti e vedi cosa esce... se il confronto torna true sei sicuro che compara il contenuto e non indirizzi o altro

misterx
16-07-2007, 19:29
dipende (tanto per cambiare :D )

il fatto che "==" sia polimorfico e' overloading... se chi ha scritto il componente doveva implementare l'uguaglianza del contenuto di due stringhe E ha RIDEFINITO l'operatore "==" per le stringhe E tale operatore era gia' definito per operare su stringhe ALLORA siamo in presenza di overriding.



scusa, per me è overriding.
Nei miei progetti uso una molteplicità di oggetti ed ogni volta che uso l'operatore == ogni classe ha la sua implementazione di ==
Difatti == lo usi per determinare se due Bitmap sono uguali e con il medesimo operatore ci confronti stringhe o altro.

Cmq, dopo aver fatto diversi esperimenti RichEdit1->Text == RichEdit2->Text confronta il contenuto di due stringhe, mi accontento, per ora.

mad_hhatter
17-07-2007, 08:41
scusa, per me è overriding.
Nei miei progetti uso una molteplicità di oggetti ed ogni volta che uso l'operatore == ogni classe ha la sua implementazione di ==
Difatti == lo usi per determinare se due Bitmap sono uguali e con il medesimo operatore ci confronti stringhe o altro.

Cmq, dopo aver fatto diversi esperimenti RichEdit1->Text == RichEdit2->Text confronta il contenuto di due stringhe, mi accontento, per ora.

ma == è un operatore, non un metodo, quindi di fatto non credo venga ereditato dalla classe base e poi sovrascritto... se tu che per ogni classe definisci una nuova semantica per ==... boh, non so

beh, con pacchetti di terze parti, a meno che non abbiamo una doc spettacolare o siano open source, devi sempre accontentarti dopo un certo punto

misterx
17-07-2007, 15:55
ma == è un operatore, non un metodo, quindi di fatto non credo venga ereditato dalla classe base e poi sovrascritto... se tu che per ogni classe definisci una nuova semantica per ==... boh, non so

beh, con pacchetti di terze parti, a meno che non abbiamo una doc spettacolare o siano open source, devi sempre accontentarti dopo un certo punto


allora non ho capito come fa BCB (sarà opera della VCL) per ogni tipo di oggetto a confrontare attraverso l'operatore == oggetti diversi :confused:

mad_hhatter
17-07-2007, 17:06
guarda, ripeto che non ho mai avuto a che fare con linguaggi che permettessero l'overloading degli operatori, quindi parlo per ipotesi...

se l'operatore è qualcosa di diverso da un metodo è probabile che esso non venga ereditato (e allora in BCB è tutto demandato alla VCL... fai presto a scoprirlo: crei una classe che eredita da una classe per la quale è definito l'operatore == e vedi se lo eredita). Io propendo per questa interpretazione perchè un operatore non sempre ha una semantica generica (pensa se tutti le classi ereditassero l'operatore +... come potresti implementare in Object la somma generica?)