Forum: PC-Programmierung C++ Operator wird nicht korrekt ausgeführt


von Thomas (Gast)


Lesenswert?

Hallo zusammen!

Bei mir hat sich in meinem Quelltext ein Problem eingesessen, was sich 
mir nicht erschließt. Ich möchte gerne in C++ eine Klasse erstellen, die 
auch vererben kann und einen Vergleichsoperator "a < b" besitzt. Diesen 
habe ich wie folgt geschrieben:

Inhalt der *.h
1
class CLCObject {
2
//foo
3
public:
4
virtual bool operator < (CLCObject& rhs);
5
6
private:
7
//bar
8
};

Inhalt der *.cpp
1
// foo
2
bool CLCObject::operator<(CLCObject& rhs) {
3
    // getLaps() und getLastTime() geben Variablenwerte
4
    // des jeweiligen Objekts in int bzw. double zurück
5
    if(this->getLaps() >= rhs.getLaps())
6
        return false;
7
    if(this->getLastTime() < rhs.getLastTime())
8
        return true;
9
    return false;
10
}
11
//bar

Wenn ich nun die Membervariablen verändere, auf die getLaps() und 
getLastTime() zugreifen, sollten sich beim Vergleich die Aussagen der 
Operatoren verändern können. Das tun sie leider nicht.

Eine einfache Anwendung wie
1
CLCObject* a;
2
CLCObject* b;
3
a.setLaps(int);
4
b.setLaps(another int);
5
if(a < b)
6
// foobar
ergibt immer den gleichen Wahrheitswert, obwohl die Werte nach 
eigentlichem händischen Auslesen andere Aussagen erzeugen.

Im Debugmodus (Ich nutze Qt-Designer) habe ich einen Breakpoint in den 
Operator herein geladen. Dieser wird allerdings nicht ausgeführt, so 
dass ich anscheinend in den Vergleich nicht hineingerate.

Habe ich in der Implementierung etwas falsch gemacht?

Besten Dank für jegliche Antworten!
    Thomas

von Ronny S. (duselbaer)


Lesenswert?

Dein Beispiel kann nicht kompilieren, a und b sind Zeiger!

Wenn dein richtiger Code auch so aussieht, vergleichst du zwei Zeiger 
und damit wird dein Operator nicht aufgerufen.

Das ist aber nur Spekulation, also, zeig mal Code!

von nicht"Gast" (Gast)


Lesenswert?

das kann so gar nicht funktionieren.

Du erstellst zwei Zeiger, weist ihnen aber keinen Speicher zu.

BTW Operatoren erstellt man außerhalb der Klasse, damit man implizite 
Typumwandlungen benutzen kann.

von Planlos (Gast)


Lesenswert?

Thomas schrieb:
> CLCObject* a;
> CLCObject* b;

du vergleichst die Pointer, nicht die Objekte...

von Frank (Gast)


Lesenswert?

Ich denke, dass das mit den Zeigern nur ein Vertipper im Beitrag war.

@TO
Bitte zeige mal den kompletten Code der Klasse und ein richtiges 
Beispiel, nicht Pseudocode.

von Rolf M. (rmagnus)


Lesenswert?

Thomas schrieb:
> Bei mir hat sich in meinem Quelltext ein Problem eingesessen, was sich
> mir nicht erschließt. Ich möchte gerne in C++ eine Klasse erstellen, die
> auch vererben kann und einen Vergleichsoperator "a < b" besitzt.

Mal abgesehen von dem, was die anderen gesagt haben: Du baust dir damit 
ein multiple-dispatch-Problem, denn die Funktion, die für den Vergleich 
aufgerufen werden muss, hängt vom Typ von zwei Objekten ab.

von Thomas (Gast)


Lesenswert?

Das ging schnell!

Kurz zum Projekt selbst: ich möchte gerne einen Rundenzähler für meine 
alte Carrerabahn erstellen. Dazu möchte ich gerne Membervariablen aus 
meinen Objekten CLCFahrer (Subklasse von CLCObjekt) vergleichen um

Header
1
class CLCDatabase;
2
3
class CLCObject
4
{
5
public:
6
////////////////////////////////////////////////////
7
    //////////////// MEMBERVARIABLEN ///////////////////
8
    ////////////////////////////////////////////////////
9
    // Membervariablen
10
    QString sTyp,
11
            sName,
12
            sShortname,
13
            sDescription;
14
    QImage baPicture;
15
    QDateTime datetimeLastModified;
16
17
    ////////////////////////////////////////////////////
18
    /////////////////// OPERATOREN /////////////////////
19
    ////////////////////////////////////////////////////
20
    virtual bool operator < (CLCObject& rhs);
21
22
signals:
23
24
public slots:
25
26
protected:
27
    CLCObject(const CLCObject&);
28
    static int iAnzahl;
29
    static map<int,CLCObject*> *mapAllObjects;
30
    static CLCDatabase *db;
31
    static ofstream outfile;
32
    int iNummer,
33
        iLaps,       // -> diese Variable wird verglichen.
34
        iTotalLaps,   
35
        iDatabaseID,
36
        iPosition;
37
    bool bPicture,
38
        bActive;
39
    vector<QTime> tLaps; // wenn iLaps identisch wird der letzte Eintrag hier verglichen
40
    vector<QTime> tCheckpoints;
41
    vector<double> dSpeed;
42
    QTime tBest, tTotal;
43
    QDate dateCreate;
44
};

Quellcode
1
QTime CLCObject::getLastTime() const {
2
    vector<QTime>::const_iterator it = this->tLaps.end();
3
    it--;
4
    return (*it);
5
}
6
7
int CLCObject::getLaps() const{
8
    return this->iLaps;
9
}
10
11
12
bool CLCObject::operator<(CLCObject& rhs) {
13
    if(this->getLaps() >= rhs.getLaps())
14
        return false;
15
    if(this->getLastTime() < rhs.getLastTime())
16
        return true;
17
    return false;
18
}

main.cpp
1
    CLCFahrer *a = new CLCFahrer("Thomas");
2
    CLCFahrer *b = new CLCFahrer("Dieter");
3
4
    // vRunde zählt den int Wert für getLaps hoch
5
    b->vRunde(QTime::currentTime());
6
    cout << "Runden a: " << a->getLaps() << endl;
7
    cout << "Runden b: " << b->getLaps() << endl;
8
9
    // hier hat a keine Runde und b 1 Runde gefahren
10
    if(*a < *b)
11
        cout << "Aussage wahr" << endl;
12
    else
13
        cout << "Aussage nicht wahr" << endl;
14
15
    a->vRunde(QTime::currentTime());
16
    a->vRunde(QTime::currentTime());
17
    cout << "Runden a: " << a->getLaps() << endl;
18
    cout << "Runden b: " << b->getLaps() << endl;
19
20
    // Jetzt hat a 2 Runden, b hat 1 Runde gefahren
21
    if(*b < *a)
22
        cout << "Aussage wahr" << endl;
23
    else
24
        cout << "Aussage nicht wahr" << endl;

Es lag auch an den Zeigern. Vielen Dank! Mit der Überführung in die *a 
funktioniert der Quellcode.

von (prx) A. K. (prx)


Lesenswert?

NB: "Why Comparison Operators Are Declared Friends"
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=523

Beachte auch den etwas inkonsequenten Umgang mit "const".

: Bearbeitet durch User
von Mikro 7. (mikro77)


Lesenswert?

Vielleicht passt es ja...
1
struct Foo
2
{ 
3
  int a,b,c ;
4
  bool operator< (Foo const &foo) const
5
  {
6
     if (a != foo.a) return a < foo.a ;
7
     if (b != foo.b) return b < foo.b ;
8
                     return c < foo.c ;
9
  }
10
} ;

D.h., bei mehreren Elementen die Gleichheit beachten.

Grüße, mikro

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Man sollte sich auch immer überlegen, ob es eigentlich logisch Sinn 
ergibt, einen bestimmten Operator zu überladen.

Thomas schrieb:
>     CLCFahrer *a = new CLCFahrer("Thomas");
>     CLCFahrer *b = new CLCFahrer("Dieter");

[...]

>     if(*b < *a)

Kann man tatsächlich davon sprechen, daß es hier darum geht, 
rauszufinden, ob das, worauf b zeigt (also der Fahrer) kleiner ist als 
das, worauf a zeigt?
Es würde also heißen: "Dieter ist kleiner als Thomas".

Und warum ist der operator< virtuell. Welchen Fall möchtest du damit 
abdecken?

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Rolf M. schrieb:
> "Dieter ist kleiner als Thomas".
Naja, weißt du, wie groß die beiden sind? :)

von beric (Gast)


Lesenswert?

Thomas schrieb:

>     if(this->getLaps() >= rhs.getLaps())
>         return false;
>     if(this->getLastTime() < rhs.getLastTime())
>         return true;
>     return false;

Und was für ein Unfug ist denn das?!
1
return this->getLastTIme() < rhs.getLastTime();
reicht volkommen aus.

von beric (Gast)


Lesenswert?

beric schrieb:
> Thomas schrieb:
>
>>     if(this->getLaps() >= rhs.getLaps())
>>         return false;
>>     if(this->getLastTime() < rhs.getLastTime())
>>         return true;
>>     return false;
>
> Und was für ein Unfug ist denn das?!return this->getLastTIme() <
> rhs.getLastTime();
> reicht volkommen aus.

Äh, vergiss es. Habe meine Brille nicht auf und getLaps() auch als 
getLastTime() gelesen. 'schuldigung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.