Topic 3: 함수 오버로딩 🔄
🎯 학습 목표
- 함수 오버로딩의 개념과 장점을 이해할 수 있다
- 오버로딩 규칙과 제약 사항을 파악할 수 있다
- 실제 상황에서 함수 오버로딩을 적절히 활용할 수 있다
🌟 함수 오버로딩이란?
“같은 이름, 다른 기능! 마치 하나의 브랜드에서 다양한 제품을 만드는 것과 같아요!”
함수 오버로딩(Function Overloading)은 같은 이름의 함수를 여러 개 정의할 수 있는 C++의 강력한 기능입니다.
🏪 편의점 비유:
- “음료수”라는 이름으로 → 콜라, 사이다, 오렌지 주스 등 판매
- “print”라는 함수로 → 정수, 실수, 문자열 등 다양한 타입 출력
- 같은 이름이지만 → 상황에 맞는 적절한 기능 수행
📚 기본 오버로딩 예제
1. 매개변수 개수가 다른 경우
#include <iostream>
using namespace std;
// 1개 매개변수 - 정수
void print(int number) {
cout << "정수: " << number << endl;
}
// 2개 매개변수 - 정수, 정수
void print(int a, int b) {
cout << "두 정수: " << a << ", " << b << endl;
}
// 3개 매개변수 - 정수, 정수, 정수
void print(int a, int b, int c) {
cout << "세 정수: " << a << ", " << b << ", " << c << endl;
}
int main() {
print(10); // 첫 번째 함수 호출
print(10, 20); // 두 번째 함수 호출
print(10, 20, 30); // 세 번째 함수 호출
return 0;
}
출력:
정수: 10
두 정수: 10, 20
세 정수: 10, 20, 30
2. 매개변수 타입이 다른 경우
#include <iostream>
#include <string>
using namespace std;
// 정수 출력
void display(int value) {
cout << "정수 값: " << value << endl;
}
// 실수 출력
void display(double value) {
cout << "실수 값: " << value << endl;
}
// 문자 출력
void display(char value) {
cout << "문자 값: " << value << endl;
}
// 문자열 출력
void display(string value) {
cout << "문자열 값: " << value << endl;
}
// 불린 출력
void display(bool value) {
cout << "불린 값: " << (value ? "true" : "false") << endl;
}
int main() {
display(42); // int 버전 호출
display(3.14); // double 버전 호출
display('A'); // char 버전 호출
display("Hello!"); // string 버전 호출
display(true); // bool 버전 호출
return 0;
}
출력:
정수 값: 42
실수 값: 3.14
문자 값: A
문자열 값: Hello!
불린 값: true
🧮 실전 예제: 계산 함수 오버로딩
📊 더하기 함수의 다양한 버전
같은 이름 ‘add’지만, 다른 상황에 맞게 동작!
// 두 정수 더하기
int add(int a, int b) {
cout << "정수 " << a << " + " << b << " = ";
return a + b;
}
// 두 실수 더하기
double add(double a, double b) {
cout << "실수 " << a << " + " << b << " = ";
return a + b;
}
// 문자열 합치기
string add(string a, string b) {
cout << "문자열 '" << a << "' + '" << b << "' = ";
return a + b;
}
int main() {
cout << add(10, 20) << endl; // 정수 버전
cout << add(3.5, 2.1) << endl; // 실수 버전
cout << add("안녕", "하세요!") << endl; // 문자열 버전
return 0;
}
출력:
정수 10 + 20 = 30
실수 3.5 + 2.1 = 5.6
문자열 '안녕' + '하세요!' = 안녕하세요!
🎨 재미있는 오버로딩: 그리기 함수
같은 ‘draw’ 함수로 다양한 모양 그리기!
#include <iostream>
#include <string>
using namespace std;
// 정사각형 그리기
void draw(int size) {
cout << "정사각형 (" << size << "x" << size << ")" << endl;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
cout << "* ";
}
cout << endl;
}
}
// 직사각형 그리기
void draw(int width, int height) {
cout << "직사각형 (" << width << "x" << height << ")" << endl;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cout << "* ";
}
cout << endl;
}
}
// 메시지 박스 그리기
void draw(string message) {
cout << "메시지 박스:" << endl;
int len = message.length();
// 위쪽 테두리
for (int i = 0; i < len + 4; i++) cout << "*";
cout << endl;
// 메시지
cout << "* " << message << " *" << endl;
// 아래쪽 테두리
for (int i = 0; i < len + 4; i++) cout << "*";
cout << endl;
}
int main() {
draw(3); // 3x3 정사각형
cout << endl;
draw(5, 2); // 5x2 직사각형
cout << endl;
draw("환영합니다!"); // 메시지 박스
return 0;
}
🔍 오버로딩 규칙과 주의사항
1. ✅ 가능한 오버로딩
// 매개변수 개수가 다름
void func(int a);
void func(int a, int b);
// 매개변수 타입이 다름
void func(int a);
void func(double a);
void func(string a);
// 매개변수 순서가 다름
void func(int a, double b);
void func(double a, int b);
// 참조와 값 전달의 차이 (주의: 모호할 수 있음)
void func(int a);
void func(int& a); // 컴파일러에 따라 에러 가능
2. ❌ 불가능한 오버로딩
// 반환값만 다른 경우 - 오류!
int func(int a);
double func(int a); // 에러: 매개변수가 같음
// 매개변수 이름만 다른 경우 - 오류!
void func(int number);
void func(int value); // 에러: 타입과 개수가 같음
// const만 다른 경우 (일반적으로 오류)
void func(int a);
void func(const int a); // 에러: 값 전달에서는 const 무시됨
3. 🤔 모호한 경우 (Ambiguous Cases)
void process(int a);
void process(double a);
// 컴파일 에러 가능성
process(3.14f); // float은 int? double? 모호함!
// 해결 방법
process((double)3.14f); // 명시적 캐스팅
process(3.14); // double 리터럴 사용
🎯 컴파일러의 함수 선택 과정
#include <iostream>
using namespace std;
void test(int a) {
cout << "int 버전: " << a << endl;
}
void test(double a) {
cout << "double 버전: " << a << endl;
}
void test(char a) {
cout << "char 버전: " << a << endl;
}
int main() {
test(42); // 정확한 일치: int 버전
test(3.14); // 정확한 일치: double 버전
test('A'); // 정확한 일치: char 버전
test(42L); // long -> int 변환: int 버전
test(3.14f); // float -> double 변환: double 버전
// test(true); // bool -> int 변환하지만 모호할 수 있음
return 0;
}
컴파일러 선택 순서:
- 완전 일치 (Exact Match)
- 승격 (Promotion): char→int, float→double
- 표준 변환 (Standard Conversion): int→double, double→int
- 사용자 정의 변환
🏆 미니 프로젝트: 만능 출력 함수
하나의 함수 이름으로 모든 것을 출력하기!
#include <iostream>
#include <string>
using namespace std;
// 정수 출력
void show(int value) {
cout << "정수: " << value << endl;
}
// 실수 출력
void show(double value) {
cout << "실수: " << value << endl;
}
// 문자열 출력
void show(string value) {
cout << "문자열: " << value << endl;
}
// 레이블과 함께 정수 출력
void show(string label, int value) {
cout << label << ": " << value << endl;
}
// 레이블과 함께 문자열 출력
void show(string label, string value) {
cout << label << ": " << value << endl;
}
// 구분선 출력
void show(char symbol, int count) {
for (int i = 0; i < count; i++) {
cout << symbol;
}
cout << endl;
}
int main() {
cout << "=== 만능 출력 함수 테스트 ===" << endl;
// 기본 출력
show(42);
show(3.14);
show("안녕하세요!");
// 레이블과 함께 출력
show("나이", 25);
show("이름", "김철수");
// 구분선
show('*', 20);
show('-', 15);
return 0;
}
🌟 오버로딩의 장점:
- 함수 이름을 기억하기 쉬움
- 직관적인 사용법
- 코드가 깔끔해짐
🎪 기본 매개변수와 오버로딩의 조합
#include <iostream>
#include <string>
using namespace std;
// 주의: 오버로딩과 기본 매개변수를 함께 사용할 때 모호성 주의!
// 거듭제곱 계산 - 오버로딩 버전
double power(double base) {
return base * base; // 제곱
}
double power(double base, int exponent) {
double result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
// 원의 정보 계산
void circleInfo(double radius) {
double area = 3.14159 * radius * radius;
double circumference = 2 * 3.14159 * radius;
cout << "반지름: " << radius << endl;
cout << "면적: " << area << endl;
cout << "둘레: " << circumference << endl;
}
// 보다 간단한 예제: 곱셈 테이블
void printMultiplicationTable(int number) {
cout << "=== " << number << "단 ===" << endl;
for (int i = 1; i <= 9; i++) {
cout << number << " x " << i << " = " << number * i << endl;
}
}
void printMultiplicationTable(int number, int limit) {
cout << "=== " << number << "단 (1~" << limit << ") ===" << endl;
for (int i = 1; i <= limit; i++) {
cout << number << " x " << i << " = " << number * i << endl;
}
}
// 학생 점수 처리
char getGrade(int score) {
if (score >= 90) return 'A';
else if (score >= 80) return 'B';
else if (score >= 70) return 'C';
else if (score >= 60) return 'D';
else return 'F';
}
string getGrade(int score, bool withComment) {
char grade = getGrade(score);
if (!withComment) {
return string(1, grade);
}
string comment;
switch(grade) {
case 'A': comment = "훌륭합니다!"; break;
case 'B': comment = "잘했어요!"; break;
case 'C': comment = "보통입니다."; break;
case 'D': comment = "노력이 필요해요."; break;
case 'F': comment = "더 힘내세요!"; break;
}
return string(1, grade) + " - " + comment;
}
int main() {
cout << "=== 거듭제곱 계산 ===" << endl;
cout << "2의 제곱: " << power(2) << endl;
cout << "2의 3제곱: " << power(2, 3) << endl;
cout << "3의 4제곱: " << power(3, 4) << endl;
cout << "\n=== 원의 정보 ===" << endl;
circleInfo(5.0);
cout << "\n=== 곱셈 테이블 ===" << endl;
printMultiplicationTable(3); // 3단 (1~9)
cout << endl;
printMultiplicationTable(5, 5); // 5단 (1~5)
cout << "\n=== 학점 부여 ===" << endl;
cout << "85점: " << getGrade(85) << endl;
cout << "95점: " << getGrade(95, true) << endl;
cout << "65점: " << getGrade(65, true) << endl;
return 0;
}
💭 생각해보기: 오버로딩 퀴즈
Q1. 다음 중 올바른 함수 오버로딩은?
// A
int calculate(int a, int b);
double calculate(int a, int b);
// B
void print(int value);
void print(double value);
// C
int add(int a);
int add(int x);
// D
void show(int a, double b);
void show(double a, int b);
💡 정답 확인
정답: B, D
- A: ❌ 반환값만 다름 (에러)
- B: ✅ 매개변수 타입이 다름
- C: ❌ 매개변수 이름만 다름 (에러)
- D: ✅ 매개변수 순서가 다름
Q2. 다음 코드에서 어떤 함수가 호출될까요?
void func(int a);
void func(double a);
void func(char a);
func(65); // ?
func('A'); // ?
func(3.14); // ?
💡 정답 확인
정답:
func(65)
→void func(int a)
- 정확한 일치func('A')
→void func(char a)
- 정확한 일치func(3.14)
→void func(double a)
- 정확한 일치
컴파일러는 항상 가장 정확히 일치하는 버전을 선택합니다!
🏆 연습 문제
다음 오버로딩 함수들을 만들어보세요:
-
🧮 계산 함수
calc
:- 두 정수 더하기:
calc(int, int)
- 두 실수 더하기:
calc(double, double)
- 세 정수 더하기:
calc(int, int, int)
- 두 정수 더하기:
-
📏 측정 함수
measure
:- 정사각형 넓이:
measure(int)
- 한 변의 길이 - 직사각형 넓이:
measure(int, int)
- 가로, 세로
- 정사각형 넓이:
-
📢 출력 함수
announce
:- 숫자 발표:
announce(int)
- 이름 발표:
announce(string)
- 성적 발표:
announce(string, int)
- 이름과 점수
- 숫자 발표:
💡 힌트:
// 예시 구조
int calc(int a, int b) {
return a + b;
}
double calc(double a, double b) {
return a + b;
}
// 이런 식으로 매개변수 타입이나 개수를 다르게 하세요!
Last updated on