오버로딩
■ 네임 맹글링 (Name Mangling)
같은 함수 이름의 구분을 위해 함수 이름 + 매개변수 정보로 고유한 이름을 부여하는 것. (+C는 오버로딩 자체가 X)
■ 오버로딩 조건
1. 매개변수 타입이 다름.
2. 매개변수 개수가 다름.
// 1. 매개변수 타입이 다름
void print(int a) {
cout << "정수 출력: " << a << endl;
}
void print(double a) {
cout << "실수 출력: " << a << endl;
}
int main() {
print(10); // 정수 출력
print(3.14); // 실수 출력
return 0;
}
// 2. 매개변수 개수가 다름
int add(int a, int b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
int main() {
cout << add(1, 2) << endl; // 두 개의 인자 사용
cout << add(1, 2, 3) << endl; // 세 개의 인자 사용
return 0;
}
■ 오버로딩 오류
1. 타입 변환이 가능한 매개변수
2. 디폴트 매개변수
3. 매개변수의 포인터 / 배열 타입
4. 함수의 반환 타입
// 1. 타입 변환이 가능한 매개변수
void print(double a) {
cout << "double: " << a << endl;
}
void print(long a) {
cout << "long: " << a << endl;
}
int main() {
// print(10); // int는 long과 double 모두로 변환 가능하므로 애매모호
return 0;
}
// 2. 디폴트 매개변수
void display(int a, int b = 5) {
cout << a << ", " << b << endl;
}
void display(int a) {
cout << a << endl;
}
int main() {
// display(10); // 디폴트 매개변수로 인해 두 함수 모두 호출 가능하므로 애매모호
return 0;
}
// 3. 매개변수의 포인터 / 배열 타입
void print(int* arr) {
cout << "포인터 호출됨" << endl;
}
void print(int arr[]) {
cout << "배열 호출됨" << endl;
}
int main() {
int data[3] = {1, 2, 3};
// print(data); // 포인터와 배열은 같은 타입으로 취급되어 애매모호
return 0;
}
// 4. 함수의 반환 타입
int getValue() {
return 10;
}
double getValue() {
return 3.14;
}
int main() {
// cout << getValue(); // 반환 타입만으로는 함수를 구별할 수 없으므로 애매모호
return 0;
}
■ 오버로딩 순서
| 정확한 매칭 v 타입 승격 변환 v 표준 타입 변환 v 사용자 정의 타입 변환 |
호출 인자 타입과 매개변수 타입이 정확히 일치. 값이 손실되지 않는 방향으로 변환. 손실 감수하고 변환, 승격보다 광범위. 클래스 타입의 변환 함수나 생성자 등을 통해 이뤄짐 |
// 정확한 매칭
void print(int a) {
cout << "정확한 타입(int) 호출됨" << endl;
}
void print(double a) {
cout << "double 타입 호출됨" << endl;
}
int main() {
print(10); // 정확한 int 타입 일치
return 0;
}
// 타입 승격 변환
void print(int a) {
cout << "int 타입 호출됨" << endl;
}
void print(char a) {
cout << "char 타입 호출됨" << endl;
}
int main() {
short s = 10;
print(s); // short에서 int로 승격 변환
return 0;
}
// 표준 타입 변환
void print(int a) {
cout << "int 버전 호출됨: " << a << endl;
}
void print(string a) {
cout << "string 버전 호출됨: " << a << endl;
}
int main() {
double num = 10.99;
print(num); // double → int 변환이 발생하여 int 버전 호출
return 0;
}
// 사용자 정의 타입 변환
class MyNumber {
public:
operator int() const { return 42; }
};
void print(int a) {
cout << "int 타입 호출됨, 값: " << a << endl;
}
void print(double a) {
cout << "double 타입 호출됨, 값: " << a << endl;
}
int main() {
MyNumber num;
print(num); // 사용자 정의 변환을 통해 MyNumber→int로 변환됨
return 0;
}
템플릿
■ 템플릿 - 타입에 관계없이 일반화된 코드를 작성하기 위한 문법.
template <typename T>
// 어떤 타입이 오던 그 타입을 T로 부르고, 일반화하려는 타입 자리에 실제 타입 대신 T를 사용.
template <typename T>
T getMax(T a, T b) {
return (a > b) ? a : b;
}
int main() {
cout << getMax(10, 20) << endl; // 정수 비교
cout << getMax(3.5, 2.7) << endl; // 실수 비교
cout << getMax(string("apple"), string("banana")) << endl; // 문자열 비교
return 0;
}
template <typename T>
void printArray(T arr[], int size) {
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
int main() {
int intArr[3] = {1, 2, 3};
char charArr[4] = {'A', 'B', 'C', 'D'};
printArray(intArr, 3); // 정수 배열 출력
printArray(charArr, 4); // 문자 배열 출력
return 0;
}
template <typename T>
void swapValues(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
int main() {
int x = 10, y = 20;
swapValues(x, y);
cout << "Swapped int values: x = " << x << ", y = " << y << endl;
double p = 3.14, q = 2.71;
swapValues(p, q);
cout << "Swapped double values: p = " << p << ", q = " << q << endl;
return 0;
}
■ 템플릿 클래스
template <typename T>
class Array
{
T data[100];
int size;
public:
Array() : size(0) {}
void add(const T &element)
{
if (size < 100)
data[size++] = element;
}
void remove()
{
if (size > 0)
size--;
}
void print()
{
for (int i = 0; i < size; i++)
cout << dtat[i] << " ";
cout << endl;
}
};
int main()
{
Array<int> arr; // 정수형 배열 생성
arr.add(10);
arr.add(20);
arr.add(30);
arr.print();
arr.remove();
arr.print();
return 0;
}'Study > C++' 카테고리의 다른 글
| C++ 기초 (3) 조건문과 반복문 (0) | 2025.12.09 |
|---|---|
| C++ 기초 (2) 배열과 함수 (0) | 2025.12.08 |
| C++ 기초 (1) 변수 (0) | 2025.12.05 |