zeiger vergleichen
-
blub² schrieb:
Ein Boot* kann nicht auf einen Motorsegelboot* zeigen.
(Ich kenne mich mit Mehrfachvererbung nicht so gut aus aber zumindest meckert der GCC.)Sicher geht das, der GCC weiss wahrscheinlich bei deinem Code nur nicht, auf welches Boot er zeigen soll, da in deinem Motorsegelboot zwei enthalten sind. Deshalb solltest du, wie volkard gesagt hat, auch virtuell erben:
class Segelboot : virtual public Boot // <- { protected: double geschw; }; class Motorboot : virtual public Boot // <- { protected: double geschw; };
Wieso übrigens
protected
Memberdaten? Ganz schlechter Stil :pGrüssli
-
0x22ff40
0x22ff50
0x22ff40
0x22ff60#include <iostream> class Boot { protected: double masse; }; class Segelboot : virtual public Boot { protected: double geschw; }; class Motorboot : virtual public Boot { protected: double geschw; }; class Motorsegelboot : public Segelboot, public Motorboot { }; int main() { Motorsegelboot msb; Motorsegelboot *msbp = &msb; Motorboot *mbp = &msb; Segelboot *sbp = &msb; Boot *bp = &msb; std::cout << msbp << std::endl; std::cout << mbp << std::endl; std::cout << sbp << std::endl; std::cout << bp << std::endl; return 0; }
Wieso übrigens protected Memberdaten? Ganz schlechter Stil :p
Mache ich normal nicht, war nur das erste was mir die Vervollständigung von Code::Blocks angeboten hat :D.
-
Keine Ahnung, was ihr mit den Codebeispielen erreichen wollt. So wie ich das sehe, kann man die Identitaet von Objekten anhand von Zeigern nur feststellen, wenn sie vom gleichen Typ sind, d.h. alles zur Basisklasse casten und dann erst vergleichen (notfalls zu void*).
-
Sorry, hatte gestern keine Zeit mehr.
0x22ff40
0x22ff50
0x22ff40
0x22ff60Das heißt, ich kann durch Zeigervergleich tatsächlich nicht feststellen, ob es sich um das selbe objekt handelt.
@vlad_tepesch,
1. Es gibt noch viel mehr Szenarien.
2. Was verstehst du unter Inhalt und Objekt? Wann zeigen für dich zwei Zeiger auf das gleiche Objekt? Was ist das gleiche Objekt?Sich er, dass waren die mir spontan eingefallen sind.
Inhalt eines zeigers ist die Adresse auf die er Zeigt.
Mit gleichem objekt meine ich das selbe ObjectIch habe 2 Zeiger und möchte wissen, ob sie auf das selbe Object zeigen.
in meinem Fall sind die Zeiger gleichen Typs, sowie die Objecte auf die sie zeigen auch
Da sollte es scheinbar keine Probleme geben.class A{ Paar* pPaar; }; class B:public A class Paar { A* pa1; A* pa2; } A* myP = new B;
Ich hole mir ein aus myP den pointer auf Paar und daraus das pPaar des anderen A*
(wenn myP = myP->pPaar->pa1 == myP, dann pp2 = myP->pPaar->pa1->pc sonst pp2 = myP->pPaar->pa2->pc)
Dann möchte ich schauen, ob die auf das selbe Paar zeigen.Das ganze ist Teil einer komplizierten Listenstruktur.
eine Liste enthält alle As.
eine andere alle Paare.
ein A, kann in mehreren Paaren vorkommen.
der Zeiger in A zeigt immer auf das beste Paar. (das ist redundant, verhindert aber das viele suche in den Listen, da das beste Paar sehr häufig gebraucht wird)
an einer stelle möchte ich feststellen, ob der Partner des untersuchten A auch das untersuchte A als besten Partner hat.Keine Ahnung, was ihr mit den Codebeispielen erreichen wollt. So wie ich das sehe, kann man die Identitaet von Objekten anhand von Zeigern nur feststellen, wenn sie vom gleichen Typ sind, d.h. alles zur Basisklasse casten und dann erst vergleichen (notfalls zu void*).
glaub nicht, dass ein Cast zu void was an der Adresse ändert, auf die der Zeiger zeigt.
-
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
0x22ff60Das 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
undpb
auf die "Sub-Ojekte" vonc
zeigen und die natürlich nicht an der gleichen Stelle im Speicher stehen. Trotzdem liefert die Vergleichsoperation in beiden Fällen 1, weilpc
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.
-
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.htmlIch 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.
-
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;
}