2010-02-28 19 views
5

Dobrze, pracuję nad książką i próbuję nauczyć się przeciążać operatora C++. Stworzyłem klasę BigInt, która pobiera pojedynczy int (początkowo ustawiony na 0) dla konstruktora. I przeciążone + = metoda i to działa dobrze w poniższym kodzie:Przeciążanie operatora + w C++

BigInt x = BigInt(2); 
x += x; 
x.print(cout); 

kod będzie wyjście 4. Tak, wtedy byłem w pracy na przeciążenia operatora globalnego + stosując następujący kod:

BigInt operator+(const BigInt lhs, const BigInt rhs) 
{ 
    BigInt returnValue(lhs); 
    returnValue += rhs; 
    return returnValue; 
} 

działa to też w porządku dla następującego kodu:

BigInt x = BigInt(1); 
BigInt y = BigInt(5); 
BigInt z = x + y; 
z.print(); 

ten wypisuje 6. Jednakże, gdy próbuję wykonać następujący kod, to po prostu nie działa. Książka nie wyjaśnia się zbyt dobrze i sugeruje, że powinna po prostu działać.

BigInt x = BigInt(1); 
BigInt z = x + 5; 
z.print(); 

ten wypisuje 1. Nie jestem pewien, dlaczego oo jest 1 gdy powinno być 6. google online i na stackoverflow, ale nie mogłem znaleźć nikogo, który był problem dokładnie tak. niektóre były blisko, ale odpowiedzi po prostu nie pasowały. Każda pomoc jest doceniana!

+4

Nie sądzę, że jest to związane z twoim problemem, ale ze względu na wydajność (a także dlatego, że jest idiomatyczne w C++) argumenty 'operator +' powinny być brane przez odniesienie do const, a nie przez wartość, np. 'Operator BigInt + (const BigInt & Lhs, const BigInt & rhs)' –

+3

Jedną z rzeczy, nad którą zastanawiam się: Dlaczego piszesz '= BigInt (1)' zamiast tylko '= 1'? Myślę, że gdybyś pokazał nam swoją pełną definicję klasy, możemy Ci pomóc lepiej :) –

+1

Zgadzam się z Tylerem. Również bardziej idiomatyczny do zainicjowania jako 'BigInt x (1);' Sposób, w jaki to robisz tworzy tymczasowy, a następnie wywołuje ctor (choć prawdopodobnie zostałby zoptymalizowany). – Dan

Odpowiedz

3

Najbardziej prawdopodobny problem to operator +=. Kod pocztowy dla niego.

+0

No cóż, @Johannes Schaub miał rację, kiedy powiedział, że został przekształcony za pomocą niejawnego castingu (wiele punktów przerwania i śledzenia kodu znalazło to dla mnie). Problem był w rzeczywistości w operatorze + =. Nie mogłem tego wymyślić bez pomocy wcześniejszego komentarza i @aaa. Dzięki Oba! –

2

Potrzebujesz przeciążenia do dodawania int do BigInt; stała 5 w twoim przykładzie jest typu int, a nie BigInt. Coś takiego powinno zadziałać:

BigInt operator+(const BigInt lhs, const int rhs) 
{ 
    BigInt returnValue(rhs); 
    returnValue += lhs; 
    return returnValue; 
} 

Możesz również chcieć jednego dla operator+(const int lhs, const BigInt rhs).

+4

To, że skompilowany kod sugeruje, że konwersja do 'BigInt' zadziałała (przez niejawną konwersję). Dlaczego kod powinien się kompilować i wydrukować '1'? To nie ma dla mnie sensu. –

+0

Tak, chyba że istnieje konstruktor inny niż "zewnętrzny", który pobiera 'int', tzn. Zapewnia konwersję z' int' na 'BigInt', potrzebujesz trzech przeciążeń' operator + '. @kevingessner, 'const' przed' int' jest bezużyteczne na liście parametrów. Z drugiej strony, typem powrotu powinno być 'const BigInt', aby uniknąć bzdur, takich jak' a + b = c; '. –

+0

Próbowałem osiągnąć powyższe rozwiązanie, a ja wciąż mam tę samą odpowiedź. –

0

Kod, który wysłałeś, wygląda dobrze i powinien działać. Problemy, które widzisz są prawie na pewno spowodowane konstruktorem kopiowania lub operatorem przypisania twojej klasy BigInt.

1

Poniższy super uproszczone kodu (minimum mogę dodać do obejmują cały swój kod i uczynić go ważnego programu wykonywalnego stand-alone):

#include <iostream> 

class BigInt 
{ 
    public: 
    BigInt(int i): _i(i) {} 
    void print() { std::cout << "BigInt(" << _i << ")\n"; } 
    void operator +=(const BigInt rhs) { _i += rhs._i; } 
    private: 
    int _i; 
}; 

BigInt operator+(const BigInt lhs, const BigInt rhs) 
{ 
    BigInt returnValue(lhs); 
    returnValue += rhs; 
    return returnValue; 
} 

int main() { 
    BigInt x = BigInt(1); 
    BigInt y = BigInt(5); 
    BigInt z = x + y; 
    z.print(); 

    BigInt ax = BigInt(1); 
    BigInt az = ax + 5; 
    az.print(); 

    return 0; 
} 

wydzielające jako przewidywalne:

BigInt(6) 
BigInt(6) 

Dokonaj minimalnych zmian w tym działającym kodzie, aby odtworzyć błąd, który obserwujesz - to oczywiście wskaże, gdzie dokładnie leży twój błąd.

Powiązane problemy