Menu
CoddyTech

Nạp chồng toán tử số học

Thuộc phần Lập trình hướng đối tượng trong hành trình C++ của Coddy. Bài học 41 trên 104.

Các toán tử số học như +, -, * và / thường được nạp chồng để các lớp tùy chỉnh hoạt động như các kiểu số dựng sẵn. Các toán tử này thường trả về một đối tượng mới thay vì sửa đổi các toán hạng.

Đây là lớp Fraction có các toán tử số học:

class Fraction {
    int numerator, denominator;
    
public:
    Fraction(int n, int d) : numerator(n), denominator(d) {}
    
    Fraction operator+(const Fraction& other) const {
        return Fraction(
            numerator * other.denominator + other.numerator * denominator,
            denominator * other.denominator
        );
    }
    
    Fraction operator*(const Fraction& other) const {
        return Fraction(numerator * other.numerator, 
                        denominator * other.denominator);
    }
};

Lưu ý rằng cả hai toán tử đều được đánh dấu là const vì chúng không sửa đổi toán hạng nào. Chúng tạo và trả về một Fraction mới chứa kết quả.

Với các toán tử gán kết hợp như +=, cách làm sẽ khác. Các toán tử này thay đổi toán hạng bên trái và trả về một tham chiếu đến toán hạng đó:

Fraction& operator+=(const Fraction& other) {
    numerator = numerator * other.denominator + other.numerator * denominator;
    denominator = denominator * other.denominator;
    return *this;
}

Một cách làm phổ biến là triển khai toán tử cơ bản dựa trên phép gán kết hợp để giảm trùng lặp code:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Sao chép đối tượng này
    result += other;            // Dùng phép gán kết hợp
    return result;
}

Cách làm này giúp cả hai toán tử luôn nhất quán và việc bảo trì dễ dàng hơn.

challenge icon

Thử thách

Dễ

Hãy tạo một lớp Money để xử lý các phép tính tiền tệ bằng cách nạp chồng toán tử số học. Bạn sẽ triển khai nhiều toán tử số học để có thể thao tác với các giá trị tiền tệ tự nhiên như với các số thông thường.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • Money.h: Định nghĩa lớp Money lưu số tiền theo đơn vị xu (dưới dạng int) để tránh các vấn đề về độ chính xác của số thực. Lớp của bạn cần hỗ trợ:
    • Hàm khởi tạo nhận số đô la và số xu dưới dạng hai số nguyên riêng biệt
    • Hàm lấy giá trị getDollars() trả về phần đô la
    • Hàm lấy giá trị getCents() trả về phần xu (0-99)
    • Các toán tử + và - được nạp chồng để trả về một đối tượng Money mới
    • Các toán tử gán kết hợp += và -= được nạp chồng để thay đổi đối tượng hiện tại và trả về tham chiếu đến đối tượng đó
    • Phương thức display() in số tiền theo định dạng $X.YY (luôn hiển thị hai chữ số cho phần xu)

    Triển khai các toán tử cơ bản (+ và -) bằng các toán tử gán kết hợp để giảm trùng lặp code, như trong bài học. Đánh dấu tất cả toán tử số học là const khi phù hợp.

  • main.cpp: Đọc bốn số nguyên từ đầu vào, biểu thị hai khoản tiền (dollars1, cents1, dollars2, cents2 trên các dòng riêng biệt). Tạo hai đối tượng Money, sau đó minh họa tất cả toán tử:
    • In "Amount 1: ", sau đó là khoản tiền thứ nhất đã được hiển thị
    • In "Amount 2: ", sau đó là khoản tiền thứ hai đã được hiển thị
    • Cộng hai khoản tiền và in "Sum: ", sau đó là kết quả
    • Lấy khoản tiền thứ hai trừ khỏi khoản tiền thứ nhất và in "Difference: ", sau đó là kết quả
    • Dùng += để cộng khoản tiền thứ hai vào khoản tiền thứ nhất, sau đó in "After +=: ", theo sau là khoản tiền thứ nhất đã được cập nhật

Với phương thức display(), hãy dùng std::setw(2) và std::setfill('0') từ <iomanip> để đảm bảo phần xu luôn hiển thị hai chữ số (ví dụ: $5.07, không phải $5.7).

Dùng std::stoi() để chuyển chuỗi đầu vào thành số nguyên. Đừng quên các chỉ thị bảo vệ header trong tệp header.

Tự làm thử

#include <iostream>
#include <string>
#include "Money.h"

using namespace std;

int main() {
    // Đọc dữ liệu đầu vào cho hai số tiền
    string line;
    
    getline(cin, line);
    int dollars1 = stoi(line);
    
    getline(cin, line);
    int cents1 = stoi(line);
    
    getline(cin, line);
    int dollars2 = stoi(line);
    
    getline(cin, line);
    int cents2 = stoi(line);
    
    // TODO: Tạo hai đối tượng Money với các giá trị đầu vào
    
    // TODO: In "Amount 1: " rồi in số tiền thứ nhất
    
    // TODO: In "Amount 2: " rồi in số tiền thứ hai
    
    // TODO: Cộng hai số tiền và in "Sum: " rồi in kết quả
    
    // TODO: Lấy số tiền thứ nhất trừ số tiền thứ hai và in "Difference: " rồi in kết quả
    
    // TODO: Dùng += để cộng số tiền thứ hai vào số tiền thứ nhất, sau đó in "After +=: " rồi in số tiền thứ nhất sau khi thay đổi
    
    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C++ online