2 Stimmen

Ungültige Operanden von Typen - C++

Ich habe eine Klasse namens ThreeDigits in C++-Code. Ich habe den +-Operanden auf diese Weise überladen:

ThreeDigits* ThreeDigits::operator+(const ThreeDigits &number) const

{
   double result= getNumber()+number.getNumber();
   ThreeDigits* new_result=new ThreeDigits(result);
   return new_result;
}

aber wenn ich über die Hauptfunktion schreibe:

    ThreeDigits* first=new ThreeDigits(2.55998);
    ThreeDigits* second=new ThreeDigits(5.666542);
    ThreeDigits* result=first+second;

Ich erhalte den folgenden Kompilierungsfehler: Ungültige Operanden der Typen ThreeDigits* und ThreeDigits* für Binäroperator+

Können Sie mir sagen, wo das Problem liegt? Danke

12voto

Matteo Italia Punkte 119470

Sie versuchen zu summieren Zeiger auf Objekte und nicht die Objekte selbst. Um den überladenen Operator aufzurufen, müssen Sie ihn auf Objekten aufrufen, wodurch die Zeiger dereferenziert werden.

Übrigens, die Erstellung all dieser Objekte mit new eine schreckliche Art, C++ zu verwenden; in C++ sollte man, anders als in Java/C#, die new nur, wenn es nötig ist, und ordnen Sie den Rest auf dem Stapel zu. Mit dem operator+ einen Zeiger auf ein neu erstelltes Objekt zurückgeben, ist eine Abscheulichkeit.

In C++ würden Sie Ihren Code folgendermaßen schreiben:

ThreeDigits ThreeDigits::operator+(const ThreeDigits &number) const
{
   return ThreeDigits(getNumber()+number.getNumber()); // construct a temporary and return it
}

// ...

ThreeDigits first(2.55998);
ThreeDigits second(5.666542);
ThreeDigits result=first+second;

Die übliche Art, arithmetische Operatoren zu überladen, besteht übrigens darin, zunächst die zuweisenden Versionen (+=, -=, ...) zu überladen und dann die "normale" Version darüber zu bauen. Weitere Informationen über das Überladen von Operatoren finden Sie in der Operatorüberladung FAQ .

3voto

Mark B Punkte 93261

Um Ihren Operator wie geschrieben zu verwenden, müssten Sie schreiben: ThreeDigits* result=*first+*second; um die Zeiger zu derefenzieren.

Ihr Betreiber hat jedoch mindestens zwei Probleme: Erstens verstößt er gegen das Prinzip der geringsten Überraschung, da er kanonisch operator+ nach Wert zurück. Zweitens wird ein Zeiger auf neuen Speicher zurückgegeben, der höchstwahrscheinlich in einer Vielzahl von Fällen ausläuft, wenn nicht darauf geachtet wird.

Es sieht so aus, als kämen Sie aus einem Java-Hintergrund, wo alles als Referenz gezählt wird. Stattdessen würde die idiomatische C++-Implementierung wie folgt aussehen:

ThreeDigits ThreeDigits::operator+(const ThreeDigits &number) const
{
   double result= getNumber()+number.getNumber();
   return ThreeDigits(result);
}

Und verwendet:

ThreeDigits first(2.55998);
ThreeDigits second(5.666542);
ThreeDigits result = first+second;

1voto

Donotalo Punkte 12360

Sie dereferenzieren die Zeiger nicht. Versuchen Sie dies:

ThreeDigits* result = *first + *second;

1voto

Oscar Korz Punkte 2437

Ihr Operator akzeptiert zwei ThreeDigits-Referenzen und gibt einen ThreeDigits-Zeiger zurück.

Um Ihren Operator so zu verwenden, wie er geschrieben wurde, müssen Sie die Dereferenz first y second :

ThreeDigits* result = *first + *second;

Dieser Betreiber hat jedoch eine ungewöhnliche Signatur. operator+ sollte einen ThreeDigits zurückgeben (d.h. keinen Zeiger auf einen). Es ist eine äußerst schlechte Praxis, wenn Ihr Operator implizit Daten neu anlegt (oder malloc), da die Benutzer dies nicht erwarten. RVO bedeutet, dass die Rückgabe einer Kopie ohnehin keine so große Sache ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X