[] 및 () 연산자 오버로딩
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 45번째.
첨자 연산자([])를 사용하면 클래스가 배열처럼 동작하여 요소에 대한 인덱스 기반 접근을 제공할 수 있습니다. 함수 호출 연산자(())는 객체를 펑터(functors)라고 알려진 호출 가능한 엔티티로 변환합니다.
다음은 첨자 연산자를 사용한 간단한 배열 래퍼(wrapper)입니다:
class IntArray {
int* data;
size_t size;
public:
IntArray(size_t s) : size(s), data(new int[s]()) {}
~IntArray() { delete[] data; }
int& operator[](size_t index) {
return data[index];
}
const int& operator[](size_t index) const {
return data[index];
}
};두 가지 버전을 제공한다는 점에 유의하세요. 하나는 (수정을 허용하는) non-const 참조를 반환하며, const 버전은 const 객체에서 작동합니다. 이를 통해 읽기와 쓰기 모두를 위해 arr[0] = 5;와 같이 작성할 수 있습니다.
함수 호출 연산자는 함수처럼 "호출"될 수 있는 객체를 생성합니다:
class Multiplier {
int factor;
public:
Multiplier(int f) : factor(f) {}
int operator()(int value) const {
return value * factor;
}
};
Multiplier triple(3);
int result = triple(10); // 30을 반환합니다펑터(Functors)는 일반 함수와 달리 호출 사이에 상태를 유지할 수 있기 때문에 강력합니다. 설정 값을 기억하는 사용자 정의 동작이 필요한 STL 알고리즘에서 흔히 사용됩니다.
챌린지
쉬움첨자 연산자(subscript operator)와 함수 호출 연산자(function call operator)를 모두 결합한 ScoreTracker 클래스를 만들어 봅시다. 이 클래스는 플레이어의 점수를 저장하고 []를 사용하여 인덱스로 접근할 수 있게 하며, 동시에 전달된 점수에 보너스 배율을 적용하는 펑터(functor) 역할도 수행합니다.
코드를 정리하기 위해 두 개의 파일을 생성합니다:
ScoreTracker.h: 플레이어 점수 배열을 관리하고 보너스를 적용할 수 있는ScoreTracker클래스를 정의합니다. 클래스에는 다음이 포함되어야 합니다:- 점수를 저장하기 위해 동적으로 할당된
int*배열 - 점수의 개수를 저장하는
size_t멤버 - 보너스 배율을 저장하는
double멤버 - 크기와 보너스 배율을 인자로 받아 모든 점수를 0으로 초기화하는 생성자
- 동적 메모리를 적절히 해제하는 소멸자
- 인덱스로 점수에 접근하기 위한 첨자 연산자
[](const 및 non-const 버전 모두) int점수를 인자로 받아 보너스 배율을 곱한 점수를 (int로) 반환하는 함수 호출 연산자()- 점수의 개수를 반환하는
getSize()메서드
non-const 첨자 연산자는 참조(reference)를 반환하여
tracker[0] = 100;과 같이 작성할 수 있도록 합니다. const 버전은 const 객체에 대해 읽기 전용 접근을 허용합니다. 함수 호출 연산자는 객체의 상태를 수정하지 않으므로const로 표시해야 합니다.- 점수를 저장하기 위해 동적으로 할당된
main.cpp: 다음 입력값들을 읽습니다 (각각 별도의 줄에 입력됨):- 플레이어 수 (크기)
- 보너스 배율 (double 형)
- 각 플레이어의 점수 (크기만큼 한 줄에 하나씩)
- 보너스를 적용할 테스트 점수
ScoreTracker를 생성하고, 첨자 연산자를 사용하여 각 플레이어의 점수를 저장한 다음 모든 점수를 표시합니다. 마지막으로 함수 호출 연산자를 사용하여 보너스가 적용된 점수를 계산합니다.출력 형식:
Player 0: <score> Player 1: <score> ... Bonus applied to <test_score>: <result>
예를 들어, 플레이어 3명, 배율 1.5, 점수 100, 200, 150, 그리고 테스트 점수 80이 입력된 경우:
Player 0: 100
Player 1: 200
Player 2: 150
Bonus applied to 80: 120입력 변환을 위해 std::stoi()와 std::stod()를 사용하세요. 헤더 파일에 헤더 가드(header guards)를 포함하는 것을 잊지 마세요.
치트 시트
첨자 연산자(subscript operator) []를 사용하면 객체에 배열처럼 접근할 수 있습니다. 함수 호출 연산자(function call operator) ()는 객체를 함수처럼 호출할 수 있게 만듭니다(함수 객체 또는 펀터).
첨자 연산자
읽기/쓰기 접근을 위해 const 버전과 비-const 버전을 모두 제공하십시오:
class IntArray {
int* data;
size_t size;
public:
IntArray(size_t s) : size(s), data(new int[s]()) {}
~IntArray() { delete[] data; }
// Non-const version: allows modification
int& operator[](size_t index) {
return data[index];
}
// Const version: read-only access
const int& operator[](size_t index) const {
return data[index];
}
};함수 호출 연산자
호출 간에 상태를 유지할 수 있는 함수 객체(functors)를 생성합니다:
class Multiplier {
int factor;
public:
Multiplier(int f) : factor(f) {}
int operator()(int value) const {
return value * factor;
}
};
Multiplier triple(3);
int result = triple(10); // Returns 30함수 객체는 저장된 설정으로 사용자 정의 동작이 필요한 STL 알고리즘과 함께 사용할 때 유용합니다.
직접 해보기
#include <iostream>
#include <string>
#include "ScoreTracker.h"
using namespace std;
// TODO: ScoreTracker 생성자 구현
ScoreTracker::ScoreTracker(size_t size, double multiplier) {
// TODO: 멤버 초기화 및 동적 배열 할당
// 모든 점수를 0으로 초기화
}
// TODO: ScoreTracker 소멸자 구현
ScoreTracker::~ScoreTracker() {
// TODO: 동적 메모리 정리
}
// TODO: non-const 첨자 연산자(subscript operator) 구현
// TODO: const 첨자 연산자(subscript operator) 구현
// TODO: 함수 호출 연산자(function call operator) 구현
// TODO: getSize 메서드 구현
size_t ScoreTracker::getSize() const {
// TODO: 점수의 개수 반환
}
int main() {
string line;
// 플레이어 수 읽기
getline(cin, line);
size_t numPlayers = stoi(line);
// 보너스 배수(multiplier) 읽기
getline(cin, line);
double multiplier = stod(line);
// TODO: numPlayers와 multiplier를 사용하여 ScoreTracker 생성
// TODO: 각 플레이어의 점수를 읽고 첨자 연산자를 사용하여 저장
// TODO: 테스트 점수 읽기
// TODO: 모든 플레이어 점수를 "Player X: <score>" 형식으로 표시
// TODO: 보너스가 적용된 결과를 "Bonus applied to <test_score>: <result>" 형식으로 표시
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.