Operator überladen, POINTER übergeben ?

Ist wahrscheinlich nur ein Objekt nicht korrekt initalisiert/konstruiert.

Alleine sowas:
Code:
  classex * help;
  help++;
ist ja schon ein Garant für undefiniertes Verhalten.

Don't panic! :)
 
Jaja, das ist schon klar.

Mein Code sieht ja auch ein wenig anderes aus, hatte das oben nur gepostet damit man das Problem schneller erkennt...


Aber ich habe jetzt doch nochmal das Noti rausgeholt, und siehe da, ihr hattet recht, es geht.

Habe aber jetzt noch ein anderes Problem was dann ab und an meinen Access Violation verursacht, wieso weiss ich bisher noch nicht, aber das bekomm ich schon noch raus ;)

Zumindest habe ich wieder was dazu gelernt ;)

D A N K E


EDIT :

Habe das Problem theoretisch behoben, nur praktisch geht er jetzt nicht mehr in den überladenen Operator.... dafür gibts jetzt nen schönen Absturz des Compilers.

Gehe jetzt mal pennen und setz mich morgen nochmal dran, wäre ja gelacht wenn das nicht zu machen wäre *ggg*
 
Zuletzt bearbeitet:
Übrigens noch einen Nachtrag ala Scott Meyers, die in meinem Beispiel falsch
implementiert waren:

1.)Scott Meyers sagt, das man die Konsistenz zu eingebauten Operatoren waren
sollte.
Der eingebaute Präfix Operator++ ist nach dem Prinzip hole und erhöhe implementiert: das heißt das Objekt wird nach einem Aufruf zwar erhöht jedoch wird vom
Präfix operator++ das alte Objekt zurückgegeben.
Bei der Postfix Form läuft es genau anders herum, zuerst wird erhöht und dann
wird der neue Wert des Objektes zurückgegeben.
Nach dieser Regel würde das so ausschauen:
Code:
const Liste operator++(Liste& l, int){

        Liste oldValue= l;
        l.weiter();
        return oldValue;
}
Da die Rückgabe per Value beim Nutzen virtueller Funktionen nur zu
Kuddelmuddel führt, da ja der oldValue, der zurückgegeben wird, nicht mehr vom Speziellen Typ ist sondern immer vom Basisklassen Typ ist ,würde ich abraten den Präfix opertor++ in deinem Fall
zu überladen oder du machst es auf die vorhin aufgeführte Art und Weise,
dann musst du dir aber darüber im Klaren sein, das dein Operator inkonnsistent,
zu den eingebauten ist.
2.)Scott Meyers sagt, der eingebauten Präfix Operator++ läßt keine zweifache
(hintereinanere) Ausführung zu. Also sowas in der Art sollte verboten werden:
Code:
intL++++;
da es
1.) nicht konsistent gegenüber der eingebauten Operatoren ist und
2.) zu Verwirrung führt da wenn der Präfix Operator++ nach dem Prinzip "hole
dann erhöhe" implementiert ist, wird intL nicht zweimal sondern nur einmal
erhöht was dann wahrsch. nicht der Absicht des Aufrufers entspricht.
Ein Ausweg aus dieser Misere ist das Rückgabeobjekt des Präfix
Operator++ als const zu deklarieren.

Diese Sachverhalte sollten dir bei der Implementierung klar sein...

Gruß

Redwing
 
Zuletzt bearbeitet:
Hi,

ich hoffe mal das ihr zwei die Geduld mit mir noch nicht ganz verloren habt, aber ich finde den Fehler einfach nicht... Ich habe mich mal an RedWing's Beispiel oben gesetzt, und versucht das auf meinen Code zu übertragen, aber jetzt kommt ein fehler nach dem nächsten...

Code:
int main()
{
 campelnzustand * a = campelnzustand::exemplar(); //Zuständeverwaltung
   campel * testampel = a->getstate();	 //Ampel 1
   campel * testampel2 = a->getstate();	//Ampel 2

   testampel2->print();	 //gibt den Zustand aus, hier gelbblinkend
   testampel2++;		  //soll in den nächsten Zustand wechseln -> ROT
//mit dem sternchen vor testampel2++ gehts nicht, dann habe ich compilerfehler
 
.....
 
}
 
 
 
//NICHT in der campel (basisklasse) definiert
 
campel* operator++(campel &help, int)
{
 help.weiter();  //NICHT als rein virtuelle methode in der basisklasse definiert, aber das dürfte eigendlich egal sein, oder ?
 return (campelnzustand::exemplar())->getstate();   //holt den aktuellen zustand der ampel und gibt ihn zurück
}



Problem jetzt :

Wenn in der Main der Befehl testampel2++; aufgerufen werden soll, dann übergeht er den einfach, er springt nirgendswo in den Code. Wenn ich jetzt beim Operator die Referenz zurückgebe, und vor das return das * setze, dann bekomme ich die nettesten Speicherfehler die man sich vorstellen kann, aber in die Operatorfunktion geht er trotzdem nicht rein.


Dann hatte ich mir gedacht, der kann ja eigendlich auch garnicht da reingehen, da die Methode ja nicht in der Basisklasse bekannt ist, jetzt habe ich die dort mit

friend campel& operator++(campel&);

bekannt gemacht, aber auch das hat nicht dazu geführt, das aus der main auch nur einmal ein Sprung in den Operator führte...


Mag zwar sein das der Fehler super offensichtlich vor meiner Nase liegt, aber ich komme nicht drauf, daher hoffe ich das einer den Fehler findet und meine Nase draufdrückt...


Thx schonmal
 
Hallo,

Wenn in der Main der Befehl testampel2++; aufgerufen werden soll, dann übergeht er den einfach, er springt nirgendswo in den Code.

da testampel2 vom Typ campel* erhöhst du mit testampel2++ den Pointer,
und diese Operation gehört ganz normal mit zu den eingebauten Operatoren,
deswegen springt er nicht in deinen Code.

Du müsstest den Operator so aufrufen:
Code:
(*testampel2)++;

Dabei ist aber notwendig das dein Operator vor der Anwendung definiert wird,
ansonsten wird der Kompiler meckern das er ihn nicht kennt.

Desweiteren:
Code:
campel* operator++(campel &help, int)
{
 help.weiter();  //NICHT als rein virtuelle methode in der basisklasse definiert, aber das dürfte eigendlich egal sein, oder ?
 return (campelnzustand::exemplar())->getstate();   //holt den aktuellen zustand der ampel und gibt ihn zurück
}

Diese Variante mag dann vielleicht funktionieren, bringt aber so einige Probleme
mit sich:

1.) Solltest du eine Referenz zurückgeben wenn du auch eine Referenz vom
Uebergabeparameter bekommst.
2.) Wenn in deiner Funktion getstate() Speicher mit new allokalisiert wird und ein
Pointer auf diesen zurückgegeben wird ist diese Aufruf im Operator
mit Sicherheit ein garantiertes Speicherloch, du gibst dann nämlich einen Pointer
auf Speicher zurück den du nie wieder freigeben kannst.
Deswegen is vielleicht folgende Definition besser:

Code:
campel& operator++(campel &help, int)
{
 help.weiter();  //NICHT als rein virtuelle methode in der basisklasse definiert, aber das dürfte eigendlich egal sein, oder ?
  return help;
}

Du könntest ja dann in deiner weiter() Funktion den state intern wechseln
oder so ähnlich.


Ich hoffe ich konnte dir helfen...

//edit Zu deiner Frage im Kommentar: Die Methode weiter() kannst du ohne
Probleme als rein virtuell deklarieren. Probiers einfach aus, du wirst sehen
es funktioniert auch mit referenzen.

Gruß

RedWing
 
Zuletzt bearbeitet:
Ich hoffe ich konnte dir helfen...

Jop, hast dem ungläubigen gerade geholfen, nun aber doch noch ne Frage, und zwar möchte ich nun statt

Code:
campel& operator++(campel & help, int)
{
 help.weiter();
   return help
}
 
 
 
NUN :
 
campel& operator++(campel & help, int)
{
 help.weiter();
   return *((campelnzustand::exemplar())->getstate());   //holt den aktuellen zustand der ampel
}

schreiben, also den NEUEN Zeiger auf den neuen Zustand zurückgeben, welcher von "getstate()" kommen sollte, nur weisst er den dann nicht in der main der testampel2 Variable zu, was mach ich denn da falsch ?
 
MFC openGL hat gesagt.:
Jop, hast dem ungläubigen gerade geholfen, nun aber doch noch ne Frage, und zwar möchte ich nun statt

Code:
campel& operator++(campel & help, int)
{
 help.weiter();
   return help
}
 
 
 
NUN :
 
campel& operator++(campel & help, int)
{
 help.weiter();
   return *((campelnzustand::exemplar())->getstate());   //holt den aktuellen zustand der ampel
}

schreiben, also den NEUEN Zeiger auf den neuen Zustand zurückgeben, welcher von "getstate()" kommen sollte, nur weisst er den dann nicht in der main der testampel2 Variable zu, was mach ich denn da falsch ?

Also
1.) Also dieses von dem Operator regeln zu lassen ist ungeschickt.
Der Rückgaberwert ist nämlich nicht für die Zuweisung gedacht sondern einzig
und allein für die mögliche Hintereinanderausführung des Operators, sprich das
man sowas schreiben kann:

Code:
(*testampel2)++++;
(wieso aber dieses nicht toll ist siehe obiger Post aber jetzt egal)

Das würde dann nämlich dem Aufruf entsprechen:

Code:
opertor++(opertor++(*testampel2));

Deswegen solltest du das Objekt "help" (denn help zeigt ja auf testampel2) selber
irgendwie intern in der Funktion weiter() verändern und dann help zurückgeben,
damit es auch veraendert ist.


Gruß

RedWing
 
Zurück