2010-02-28 53 views
5

Ok, tôi đang làm việc thông qua một cuốn sách và cố gắng tìm hiểu quá tải toán tử C++. Tôi tạo ra một lớp BigInt có một int (ban đầu được thiết lập là 0) cho hàm tạo. Tôi quá tải + = phương pháp và nó chỉ hoạt động tốt trong các mã sau:Toán tử quá tải + trong C++

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

Mã này sẽ ra 4. Vì vậy, sau đó tôi đã làm việc trên quá tải toán tử toàn cầu + sử dụng đoạn mã sau:

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

này cũng hoạt động tốt cho đoạn mã sau:

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

này in ra 6. Tuy nhiên, khi tôi cố gắng để thực hiện đoạn mã sau, nó chỉ không hoạt động. Cuốn sách không giải thích rõ ràng và ngụ ý rằng nó chỉ đơn giản là làm việc.

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

này in ra 1. Tôi không chắc chắn lý do tại sao z là 1 khi nó phải được 6. Tôi googled trực tuyến và trên stackoverflow nhưng tôi không thể tìm thấy bất cứ ai khác mà đã có một vấn đề chính xác như thế này. một số đã gần, nhưng các câu trả lời chỉ không phù hợp. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao!

+4

Tôi không nghĩ rằng điều này có liên quan đến vấn đề của bạn, nhưng vì lợi ích của hiệu quả (và cũng vì nó là thành ngữ trong C++), các đối số cho 'toán tử +' phải được lấy bởi tham chiếu const, chứ không phải theo giá trị, ví dụ: 'BigInt operator + (const BigInt & lhs, const BigInt & rhs)' –

+3

Một điều tôi cứ tự hỏi: Tại sao bạn viết '= BigInt (1)' thay vì chỉ '= 1'? Tôi nghĩ nếu bạn cho chúng tôi thấy định nghĩa lớp học hoàn chỉnh của mình, chúng tôi có thể giúp bạn tốt hơn :) –

+1

Tôi đồng ý với Tyler. Ngoài ra thành ngữ hơn để khởi tạo như 'BigInt x (1);' Cách bạn đang làm nó tạo ra một tạm thời và sau đó gọi ctor bản sao (mặc dù điều đó có lẽ sẽ được tối ưu hóa ra). – Dan

Trả lời

3

vấn đề có thể xảy ra nhất là trong toán tử +=. Mã bưu điện cho nó.

+0

Vâng, @Johannes Schaub đã đúng khi ông nói rằng nó đã được chuyển đổi bằng cách đúc ngầm (rất nhiều breakpoints và mã truy tìm thấy rằng một trong cho tôi). Vấn đề thực ra là trong toán tử + =. Tôi không thể tìm ra điều đó với sự giúp đỡ của bình luận trước đó và @aaa. Cảm ơn cả hai! –

2

Bạn cần quá tải để thêm nội dung vào BigInt; hằng số 5 trong ví dụ của bạn là kiểu int, không phải là BigInt. Một cái gì đó như thế này sẽ hoạt động:

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

Bạn cũng có thể muốn một cho operator+(const int lhs, const BigInt rhs).

+4

Mã được biên dịch ngụ ý rằng việc chuyển đổi sang 'BigInt' hoạt động (bằng cách chuyển đổi ngầm). Tại sao mã phải biên dịch và in '1'? Điều đó không có ý nghĩa với tôi. –

+0

Có, trừ khi có một hàm tạo không phải là 'explicit' nhận 'int', tức là cung cấp cho việc chuyển đổi từ' int' thành 'BigInt', bạn cần ba quá tải của' operator + '. @kevingessner, 'const' trước' int' là loại vô dụng trong danh sách tham số. Mặt khác, kiểu trả về có thể là 'const BigInt' để tránh vô nghĩa như' a + b = c; '. –

+0

Tôi đã thử giải pháp trên và tôi vẫn nhận được câu trả lời tương tự. –

0

Mã bạn đã đăng có vẻ ổn và sẽ hoạt động. Các vấn đề bạn thấy gần như chắc chắn là do người tạo bản sao hoặc toán tử gán của lớp BigInt của bạn.

1

Các mã sau siêu đơn giản (tối thiểu tôi có thể thêm vào bao gồm tất cả các mã của bạn và làm cho nó vào một chương trình thực thi độc lập có hiệu lực):

#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; 
} 

phát ra, như dự đoán:

BigInt(6) 
BigInt(6) 

Vui lòng thực hiện các thay đổi tối thiểu có thể cho mã hoạt động này để tạo lại lỗi mà bạn quan sát - tất nhiên điều đó sẽ cho biết chính xác lỗi của bạn nằm ở đâu.