Skip to Content
💻 코리아IT아카데미 신촌 - 프로그래밍 학습 자료
C++ 프로그래밍Unit 5: 함수 기초Topic 3: 함수 오버로딩

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

컴파일러 선택 순서:

  1. 완전 일치 (Exact Match)
  2. 승격 (Promotion): char→int, float→double
  3. 표준 변환 (Standard Conversion): int→double, double→int
  4. 사용자 정의 변환

🏆 미니 프로젝트: 만능 출력 함수

하나의 함수 이름으로 모든 것을 출력하기!

#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) - 정확한 일치

컴파일러는 항상 가장 정확히 일치하는 버전을 선택합니다!

🏆 연습 문제

다음 오버로딩 함수들을 만들어보세요:

  1. 🧮 계산 함수 calc:

    • 두 정수 더하기: calc(int, int)
    • 두 실수 더하기: calc(double, double)
    • 세 정수 더하기: calc(int, int, int)
  2. 📏 측정 함수 measure:

    • 정사각형 넓이: measure(int) - 한 변의 길이
    • 직사각형 넓이: measure(int, int) - 가로, 세로
  3. 📢 출력 함수 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