산술 연산자 오버로딩
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 41번째.
+, -, *, /와 같은 산술 연산자는 사용자 정의 클래스가 내장 숫자 타입처럼 동작하도록 하기 위해 흔히 오버로드됩니다. 이러한 연산자들은 일반적으로 피연산자를 수정하는 대신 새로운 객체를 반환합니다.
산술 연산자가 포함된 Fraction 클래스입니다:
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);
}
};두 연산자 모두 피연산자를 수정하지 않으므로 const로 표시되어 있음에 유의하세요. 이들은 결과를 담은 새로운 Fraction을 생성하여 반환합니다.
+=와 같은 복합 대입 연산자의 경우, 패턴이 다릅니다. 이들은 왼쪽 피연산자를 수정하고 그에 대한 참조를 반환합니다:
Fraction& operator+=(const Fraction& other) {
numerator = numerator * other.denominator + other.numerator * denominator;
denominator = denominator * other.denominator;
return *this;
}일반적인 관행은 복합 대입 연산자를 사용하여 기본 연산자를 구현함으로써 코드 중복을 줄이는 것입니다:
Fraction operator+(const Fraction& other) const {
Fraction result = *this; // 이 객체를 복사합니다
result += other; // 복합 대입 연산자를 사용합니다
return result;
}이 접근 방식은 두 연산자 모두 일관성을 유지하도록 보장하며 유지보수를 더 쉽게 만듭니다.
챌린지
쉬움산술 연산자 오버로딩을 사용하여 통화 계산을 처리하는 Money 클래스를 만들어 보겠습니다. 일반 숫자처럼 자연스럽게 금액 값을 다룰 수 있도록 여러 산술 연산자를 구현하게 됩니다.
코드를 구성하기 위해 두 개의 파일을 생성합니다:
Money.h: 부동 소수점 정밀도 문제를 피하기 위해 금액을 센트 단위(int)로 저장하는Money클래스를 정의합니다. 클래스는 다음을 지원해야 합니다:- 달러와 센트를 별도의 정수로 받는 생성자
- 달러 부분을 반환하는 게터
getDollars() - 센트 부분(0-99)을 반환하는 게터
getCents() - 새로운
Money객체를 반환하는 오버로드된+및-연산자 - 현재 객체를 수정하고 그 참조를 반환하는 오버로드된
+=및-=복합 대입 연산자 - 금액을
$X.YY형식으로 출력하는display()메서드 (센트는 항상 두 자리로 표시)
강의에서 보여준 것처럼 코드 중복을 줄이기 위해 기본 연산자(
+및-)를 복합 대입 연산자를 사용하여 구현하세요. 모든 산술 연산자는 적절한 경우const로 표시되어야 합니다.main.cpp: 입력에서 두 개의 금액을 나타내는 4개의 정수(각 줄에 dollars1, cents1, dollars2, cents2)를 읽습니다. 두 개의Money객체를 생성한 다음 모든 연산자를 시연합니다:"Amount 1: "를 출력한 후 첫 번째 금액을 표시합니다."Amount 2: "를 출력한 후 두 번째 금액을 표시합니다.- 두 금액을 더하고
"Sum: "을 출력한 후 결과를 표시합니다. - 첫 번째 금액에서 두 번째 금액을 빼고
"Difference: "를 출력한 후 결과를 표시합니다. +=를 사용하여 두 번째 금액을 첫 번째 금액에 더한 다음,"After +=: "를 출력하고 수정된 첫 번째 금액을 표시합니다.
display() 메서드의 경우, <iomanip>의 std::setw(2)와 std::setfill('0')을 사용하여 센트가 항상 두 자리로 표시되도록 하세요 (예: $5.7이 아닌 $5.07).
std::stoi()를 사용하여 입력 문자열을 정수로 변환하세요. 헤더 파일에 헤더 가드를 포함하는 것을 잊지 마세요.
치트 시트
+, -, *, /와 같은 산술 연산자는 사용자 정의 클래스가 내장 숫자 타입처럼 동작하도록 오버로드될 수 있습니다. 이러한 연산자들은 일반적으로 피연산자를 수정하는 대신 새로운 객체를 반환합니다.
기본 산술 연산자는 두 피연산자 중 어느 것도 수정하지 않으므로 const로 표시되어야 합니다:
Fraction operator+(const Fraction& other) const {
return Fraction(
numerator * other.denominator + other.numerator * denominator,
denominator * other.denominator
);
}+= 및 -=와 같은 복합 대입 연산자는 왼쪽 피연산자를 수정하고 그에 대한 참조를 반환합니다:
Fraction& operator+=(const Fraction& other) {
numerator = numerator * other.denominator + other.numerator * denominator;
denominator = denominator * other.denominator;
return *this;
}일반적인 관행은 코드 중복을 줄이기 위해 복합 대입 연산자를 사용하여 기본 연산자를 구현하는 것입니다:
Fraction operator+(const Fraction& other) const {
Fraction result = *this; // 이 객체를 복사합니다
result += other; // 복합 대입을 사용합니다
return result;
}직접 해보기
#include <iostream>
#include <string>
#include "Money.h"
using namespace std;
int main() {
// 두 개의 금액에 대한 입력을 읽습니다
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: 입력된 값으로 두 개의 Money 객체를 생성합니다
// TODO: "Amount 1: "을 출력한 뒤 첫 번째 금액을 표시합니다
// TODO: "Amount 2: "를 출력한 뒤 두 번째 금액을 표시합니다
// TODO: 두 금액을 더하고 "Sum: "을 출력한 뒤 결과를 표시합니다
// TODO: 첫 번째 금액에서 두 번째 금액을 빼고 "Difference: "를 출력한 뒤 결과를 표시합니다
// TODO: +=를 사용하여 첫 번째 금액에 두 번째 금액을 더한 다음, "After +=: "를 출력하고 수정된 첫 번째 금액을 표시합니다
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.