zeiger vergleichen



  • vlad_tepesch schrieb:

    ...Das heißt, ich kann durch Zeigervergleich tatsächlich nicht feststellen, ob es sich um das selbe objekt handelt....

    ... oder Du überdenkst, was Du unter "dasselbe Objekt" verstehst.
    Die Frage ist IMHO nicht so trivial wie sie auf den ersten Blick scheint. Vielleicht könnte man sogar andersherum definieren: "Zwei Zeiger zeigen genau dann auf dasselbe Objekt, wenn sie denselben Wert haben"
    Wäre eine mögliche Definition ... eine andere (durchaus auch mit Existenzberechtigung, eher durch den Begriff des "Fachobjekts" geprägt) ist:
    "Es handelt sich genau dann um dasselbe Objekt, wenn der operator==() true zurückliefert."
    gibt bestimmt noch mehr ...

    Gruß,

    Simon2.



  • ... durch Zeigervergleich tatsächlich nicht feststellen ...

    Aber nur, weil die Zeiger nicht vom gleichen Typ sind.

    Es handelt sich genau dann um dasselbe Objekt, wenn der operator==() true zurückliefert.

    Nein, da ich selbst operator==() mit Semantik belegen kann. Auch ist 5 == 5, aber 5 kann an unterschiedlichen Stellen gespeichert sein, so dass es sich nicht um das selbe Objekt handelt, nur um das gleiche. Spielt das eine Rolle? Ja!



  • blub² schrieb:

    #include <iostream>
    
    class Boot
    {
        protected:
        double masse;
    };
    
    class Segelboot : public Boot
    {
        protected:
        double geschw;
    };
    
    class Motorboot : public Boot
    {
        protected:
        double geschw;
    };
    
    class Motorsegelboot : public Segelboot, public Motorboot
    {
    }
    

    Hier sollte außerdem virtuelle Vererbung benutzt werden, da man sonst 2 Isntanzen der Klasse Boot in Motorsegelboot hat.

    class Boot
    {
        double masse;
        double geschw;
    };
    
    class Segelboot : virtual public Boot
    {
        int masten;
    };
    
    class Motorboot : virtual public Boot
    {
        int ps;
    };
    class Motorsegelboot : virutal public Segelboot, virtual public Motorboot
    {
    }
    


  • Simon2 schrieb:

    "Es handelt sich genau dann um dasselbe Objekt, wenn der operator==() true zurückliefert."

    Das ist der kleine, aber feine Unterschied zwischen 'das gleiche' und 'das selbe'
    Wenn man sagt, "der hat das selbe Hemd an, wie ich.", dann ist das unmöglich (wenn man mal Viele-Welten-Theorien weglässt ;)).



  • vlad_tepesch schrieb:

    Sorry, hatte gestern keine Zeit mehr.

    0x22ff40
    0x22ff50
    0x22ff40
    0x22ff60

    Das heißt, ich kann durch Zeigervergleich tatsächlich nicht feststellen, ob es sich um das selbe objekt handelt.

    Klar kannst Du. Du darfst Dich nur nicht auf die textuelle Repräsentierung eines nach void* konvertierten Zeigers verlassen, die Du über operator<<(ostream&,void*) bekommst. Eine Konvertierung eines Zeigers in einen anderen Typen (deren Klassen in einer Vererbungsbeziehung stehen) kann die interne Repräsentierung ändern. Das, was Dir std::cout da anzeigt ist völlig uninteressant. Beispiel:

    #include <iostream>
    
    class A {int a;};
    class B {int b;};
    class C : A, B {};
    
    int main() {
      C c;
      A* pa = &c;
      B* pb = &c;
      C* pc = &c;
      std::cout << pa << '\n';
      std::cout << pb << '\n';
      std::cout << pc << '\n';
      std::cout << (pa==pc) << '\n';
      std::cout << (pb==pc) << '\n';
    }
    

    Hier ist zu erwarten, dass die ersten drei Ausgaben nicht gleich sind, da pa und pb auf die "Sub-Ojekte" von c zeigen und die natürlich nicht an der gleichen Stelle im Speicher stehen. Trotzdem liefert die Vergleichsoperation in beiden Fällen 1, weil pc jeweils implizit zu A* bzw B* konvertiert und damit eventuell angepasst wird.

    Bei mir bekomme ich folgendes Ergebnis:

    0x22ff70
    0x22ff74
    0x22ff70
    1
    1
    

    I rest my case.

    Gruß,
    SP



  • knivil schrieb:

    Es handelt sich genau dann um dasselbe Objekt, wenn der operator==() true zurückliefert.

    Nein, da ich selbst operator==() mit Semantik belegen kann.

    Was natürlich gemeint war: Wenn ein Zeigervergleich (==) true liefert, dann zeigen sie auf das selbe Objekt (oder der eine zeigt auf ein Sub-Objekt des anderen). Das Überladen von operator== bei Zeigern ist nicht möglich.

    Gruß,
    SP



  • knivil schrieb:

    ...

    Es handelt sich genau dann um dasselbe Objekt, wenn der operator==() true zurückliefert.

    Nein, da ich selbst operator==() mit Semantik belegen kann....

    Eben - genau deswegen.

    Es ist einfach eine andere Defintion dessen, welche Unterschiede interessieren - und welche eben nicht.
    Die "Zeigerdefinition" ist auch nicht so "unantastbar", wie es auf den ersten Blick scheint. So können Betriebssysteme durchaus zu unterschiedlichen Zeitpunkten Speicheradressen auf unterschiedliche "physikalische" Speicheradresse abbilden (bis hin zum Swapping auf Platte) ... oder von unterschiedlichen (auch parallelen) Prozessen dieselben Anwendungsadressräume auf unterschiedliche "physikalische".
    Hin bis zu der Frage, ob es sich um dasselbe Objekt handelt, wenn es durch den Stromfluss anderer Elektronen in der Elektronik abgebildet wird.
    (wobei auch die Frage nach "demselben Elektron" ebenso spannend ist)

    Es ist immer die Frage: Welche Aspekte lasse ich unter den Tisch fallen...

    Gruß,

    Simon2.



  • vlad_tepesch schrieb:

    ...Das ist der kleine, aber feine Unterschied zwischen 'das gleiche' und 'das selbe'...

    Nunja, diese beiden Ausdrücke sind aber nicht so streng definiert (oder gar gegeneinander abgegrenzt), dass man sie ohne weitere Erklärung verwenden oder zuordnen kann.
    "Das selbe" drückt zwar den Versuch aus, möglichst viele Übereinstimmungen zu finden, während "das gleiche" mehr Raum lässt für Abweichungen - aber auch das üblicherweise nur im direkten Gegensatz. Wenn ich also zurückfrage "Dasselbe oder das Gleiche?" will ich genau auf die "Einschränkungen"/"Unterschiede" hinaus ... wenn ich dagegen eines von beiden verwende, betont man üblicherweise nur die Gemeinsamkeiten.

    In Diskussionen kann es sehr hilfreich sein, diese beiden Begriffe bewusst (und auf den jeweiligen Kontext hin definiert) zu verwenden, aber allgemeingültig klären sie IMHO das Problem nicht.

    Mal eine kleine Gegenfrage: Bist Du nach Lesen dieses Posts noch derselbe wie davor?

    Gruß,

    Simon2.



  • Jetzt wird's philosophisch. Die deutsche Sprache ist nicht exakt und kann so nicht auf Computersprachen abgebildet werden. Was im Hintergrund laeuft a la swapping oder tatsaechliche physikalische Speicherbereiche ist nebensachlich, da es sauber vom Betriebssystem gekapselt wird (fuer gewoehnlich). Auch ueber Elektronen sagt der C++ Standard nichts aus.

    Bist Du nach Lesen dieses Posts noch derselbe wie davor?

    Im Sinne von C++ ja. Aber hier fuehrst du etwas neues ein: vorher und nachher.



  • knivil schrieb:

    Jetzt wird's philosophisch. ...

    Japp - das ist aber auch immer der interessantere Teil. 😃

    knivil schrieb:

    ...Was im Hintergrund laeuft a la swapping oder tatsaechliche physikalische Speicherbereiche ist nebensachlich, da es sauber vom Betriebssystem gekapselt wird (fuer gewoehnlich). Auch ueber Elektronen sagt der C++ Standard nichts aus...

    Aber auch nichts darüber, was "dasselbe Objekt" sei.
    Deshalb sehe ich nicht, wo ein "Zeigervergleich" C++iger sei als ein "operator==()"-Vergleich.

    knivil schrieb:

    ...Aber hier fuehrst du etwas neues ein: vorher und nachher.

    Naja, sooo neu ist das im Zusammenhang mit Objektvergleichen nicht, denn es ist doch eher der absolute Ausnahmefall, dass 2 zu vergleichende Referenzen exakt zum selben Zeitpunkt erzeugt wurden.

    Auch wenn ich von Dir spreche mit Jemandem, der Dich gestern gesehen hat, wird die Frage sein, ob wir von demselben sprechen.

    Gruß,

    Simon2.


  • Administrator

    vlad_tepesch schrieb:

    Mit gleichem objekt meine ich das selbe Object 😉

    Frage ist nicht beantwortet. Mir geht es um dasselbe Objekt im Speicher oder dasselbe polymorphe Objekt.

    Ein wenig Code zur Vedeutlichung:

    #include <iostream>
    
    struct Base
    {
    	virtual ~Base() { } // für dynamic_cast
    
    	char dummy;
    };
    
    struct DLeft : Base
    {
    	char dummy;
    };
    
    struct DRight : Base
    {
    	char dummy;
    };
    
    struct DCenter : DLeft, DRight
    {
    	char dummy;
    };
    
    int main()
    {
    	DCenter c;
    	Base* bl = static_cast<DRight*>(&c);
    	Base* br = static_cast<DLeft*>(&c);
    
    	std::cout << (bl == br) << std::endl;
    
    	DCenter* cl = dynamic_cast<DCenter*>(bl);
    	DCenter* cr = dynamic_cast<DCenter*>(br);
    
    	std::cout << (cl == cr) << std::endl;
    
    	return 0;
    }
    

    Da können nicht mal mehr Leute was dagegen sagen, welche verlangen, dass die beiden Zeiger vom gleichen Typ sind 😉
    Die erste Ausgabe ist 0, es sind zwei unterschiedliche Base Objekte, auf welche die Zeiger verweisen. Das polymorphe Objekt ist allerdings dasselbe, wie es die zweite Ausgabe nochmals verdeutlicht.

    Grüssli



  • zum thema dasselbe (wird schainbar zusammengeschrieben - wusste ich auch nicht):
    http://www.spiegel.de/kultur/zwiebelfisch/0,1518,311593,00.html

    Ich wurde früher öfter auf diesen Unterschied aufmerksam gemacht, wenn ich das falsche benutzt habe.

    Dravere schrieb:

    vlad_tepesch schrieb:

    Mit gleichem objekt meine ich das selbe Object 😉

    Frage ist nicht beantwortet. Mir geht es um dasselbe Objekt im Speicher oder dasselbe polymorphe Objekt.

    Ein wenig Code zur Vedeutlichung:

    #include <iostream>
    
    struct Base
    {
    	virtual ~Base() { } // für dynamic_cast
    
    	char dummy;
    };
    
    struct DLeft : Base
    {
    	char dummy;
    };
    
    struct DRight : Base
    {
    	char dummy;
    };
    
    struct DCenter : DLeft, DRight
    {
    	char dummy;
    };
    
    int main()
    {
    	DCenter c;
    	Base* bl = static_cast<DRight*>(&c);
    	Base* br = static_cast<DLeft*>(&c);
    
    	std::cout << (bl == br) << std::endl;
    
    	DCenter* cl = dynamic_cast<DCenter*>(bl);
    	DCenter* cr = dynamic_cast<DCenter*>(br);
    
    	std::cout << (cl == cr) << std::endl;
    
    	return 0;
    } :confused:
    

    Da können nicht mal mehr Leute was dagegen sagen, welche verlangen, dass die beiden Zeiger vom gleichen Typ sind 😉
    Die erste Ausgabe ist 0, es sind zwei unterschiedliche Base Objekte, auf welche die Zeiger verweisen. Das polymorphe Objekt ist allerdings dasselbe, wie es die zweite Ausgabe nochmals verdeutlicht.

    Grüssli

    Der Fall sollte doch recht eindeutig sein, oder nicht?
    folgendes ist noch fraglicher, da du keine virtuelle Vererbung benutzt, gibt es ja tatsächlich 2 Bases.

    int main()
    {
    	DCenter c;
    	DLeft  * dl = static_cast<DLeft *>(&c);
    	DRight * dr = static_cast<DRight *>(&c);
    
    	std::cout << (bl == br) << std::endl;
    
    	Base* bl = static_cast<Base*>(dl);
    	Base* br = static_cast<Base*>(dr);
    
    	std::cout << (cl == cr) << std::endl;
    
    	return 0;
    }
    


  • vlad_tepesch schrieb:

    zum thema dasselbe (wird schainbar zusammengeschrieben - wusste ich auch nicht):
    http://www.spiegel.de/kultur/zwiebelfisch/0,1518,311593,00.html...

    Leider beantwortet es die hier entscheidene Frage genau gar nicht. 😃

    Gruß,

    Simon2.


  • Administrator

    vlad_tepesch schrieb:

    Der Fall sollte doch recht eindeutig sein, oder nicht?

    Ich frage ja dich, was du darunter verstehst. Es geht aus deinen Aussagen nämlich nicht eindeutig hervor, ob du mit "demselben Objekt" das aktuelle Objekt meinst, auf welches der Zeiger gerade zeigt, oder das gesamte polymorphe Objekt.

    Das verändert nämlich dann auch entscheidend die Antwort. Wenn man vom Objekt ausgeht, auf welches gerade gezeigt wird, dann ist es definiert, dass man über die Zeigergleichheit prüfen kann, dass es die gleichen Objekte sind, schliesslich kann an der gleichen Speicheradresse nicht doppelter Speicher vorhanden sein. Wenn man allerdings davon ausgeht, dass man prüfen möchte, ob es das gleiche polymorphe Objekte ist, dann geht das nicht mehr. Ausser man würde zuerst die Zeiger auf die Basisklassen-Objekte per dynamic_cast in Zeiger auf die entsprechenden Most-Derived-Klassenobjekte umwandeln.

    Grüssli



  • Simon2 schrieb:

    vlad_tepesch schrieb:

    ...Das ist der kleine, aber feine Unterschied zwischen 'das gleiche' und 'das selbe'...

    Nunja, diese beiden Ausdrücke sind aber nicht so streng definiert (oder gar gegeneinander abgegrenzt), dass man sie ohne weitere Erklärung verwenden oder zuordnen kann.

    Du kannst nicht für die selbe Straftat zweimal verurteilt werden, aber für die gleiche schon, hab ich mal gehört. Also für die Geschwindigkeitsüberschreitung am 12.12.1912 um 12:12 kannst du nur einmal verurteilt werden, aber wenn du nochmal die gleiche Straftat (Geschwindigkeitsüberschreitung) zu einem anderen Zeitpunkt nochmal begehst, kannst du natürlich wieder verurteilt werden.



  • kann mir jemand helfen herauszufinden was ich ändern muss am Code wegen dem Fehler?
    Hab schon alles versucht was mir einfiel...

    struct element{char *begriff; int seite1; int seite2; int seite3;};
    bool suche_genau(element *verzeichnis,const char* suchbegriff,int anz)
    {
    if(strcmp(verzeichnis->begriff,suchbegriff)==0){
    anz=1;
    return true;
    }
    else
    return false;
    }
    int main()
    {
    element stichwortverzeichnis[1000]=
    {{"Atom",1,45,387},{"Betastrahlung",2,48,793},{"Gammastrahlung",17,49,845}};
    int anzahl=0;
    const char
    suchbegriff="Atom";

    if(suche_genau(element* ,char ,int)==true)
    cout<<"Treffer in Seite "<<stichwortverzeichnis.seite1<<stichwortverzeichnis.seite2<<stichwortverzeichnis.seite3<<endl;
    else
    cout<<"kein Treffer"<<endl;
    return 0;
    }



  • forever21 schrieb:

    kann mir jemand helfen herauszufinden was ich ändern muss am Code wegen dem Fehler?
    Hab schon alles versucht was mir einfiel...

    Ähm, Zusammenhang? 😕

    Mach einen eigenen Thread auf und verwende [cpp]-Tags, um den Code zu formatieren, sonst werden ihn sich nicht viele Leute anschauen.



  • sorry



  • Einsperrer schrieb:

    ...Du kannst nicht für die selbe Straftat zweimal verurteilt werden, aber für die gleiche schon, hab ich mal gehört. Also für die Geschwindigkeitsüberschreitung am 12.12.1912 um 12:12 kannst du nur einmal verurteilt werden, aber wenn du nochmal die gleiche Straftat (Geschwindigkeitsüberschreitung) zu einem anderen Zeitpunkt nochmal begehst, kannst du natürlich wieder verurteilt werden.

    Wir können gerne das Forum füllen mit mehr oder minder scharfen Begriffsdefinitionen aus anderen Disziplinen - bringt aber nicht weiter, weil es letzlich dabei bleibt: Im C++-Standard wird nirgends definiert, was "dasselbe" oder "das Gleiche" sei... (wenn doch, bitte ich um entsprechende Quellenangabe).
    ... und selbst in der Informatik ist mir nicht bekannt, dass diese Begriffe scharf definiert seien (aber auch hier bin ich belehrbar).

    Gruß,

    Simon2.



  • für gleiche Objekte gibt es den Gleichheitsoperator, also ist es schon geregelt.

    für mich ist ein gleiches objekt:
    *this == otherObject

    dasselbe objekt:
    this == &otherObject
    ich meine es ist auch dasselbe, wenn pointer A auf die Basisklasse zeigt und Pointer X auf die 230te Ableitung und das Objekt vom Typ 560te Ableitung ist.
    es wurde einmal ein object erzeugt, egal wie die Pointer darauf typisiert sind, möchte ich wissen, ob es dasselbe ist wie mein Vergleichsppointer

    Das Frage ist aber eher theoritischer Natur, da bei mir die Pointer gleichsind, und das Objekt tatsächlich vom selben typ wie die Pointer sind (und auch keine Mehrfachvererbung in der Hierarchie vorkommt).


Anmelden zum Antworten