[C++] C++ 컴파일러에서 함수를 오버로딩(Overloading)하는 과정
2022. 2. 8. 23:03ㆍLanguages/C++
*<씹어먹는 C++>을 보며 공부하여 정리한 글입니다.
1. 함수 오버로딩(Overloading)이란?
- 동일한 이름의 함수를 매개변수 타입, 매개변수의 개수에 따라 구분하여 여러 개 생성 가능하게 하는 것을 말합니다.
- 비슷한 기능인데 함수 이름이 각각 달라, 개별적으로 기억할 수고가 없어져서 편리합니다.
- 함수의 리턴 타입으로도 구분이 가능하나, 리턴 타입만 다르고 매개변수까지 똑같은 함수를 만드는 것은 불가능
#include <iostream>
// 함수 오버로딩
int Add(int x, double y) { return x + y; }
int Add(int x, int y) { return x + y; }
double Add(double x, double y) { return x + y; }
// int Add(double x, double y)는 double Add(double x, double y)가 있어서 불가능
int main() {
int num1 = Add(3, 5);
int num2 = Add(3, 5.5);
double num3 = Add(3.5, 6.5);
std::cout << num1 << std::endl; // 8
std::cout << num2 << std::endl; // 8.5
std::cout << num3 << std::endl; // 10.0
}
2. C++ 컴파일러에서 함수를 오버로딩하는 과정
- 함수의 자기 자신과 타입이 정확히 일치하는 함수를 찾는다.
- 1번에서 찾지 못할 경우, 아래와 같은 형변환을 통해 일치하는 함수를 찾는다.
- char, unsigned char, short → int로 변환
- unsigned short는 int의 크기에 따라 int 또는 unsigned int로 변환
- float → double로 변환
- enum → int로 변환
- 1, 2번에서도 찾지 못할 경우, 다음과 같이 좀 더 포괄적인 형변환을 통해 일치하는 함수를 찾는다.
- 임의의 숫자(numeric) 타입은 다른 숫자 타입으로 변환 (float → int)
- enum 또한 임의의 숫자 타입으로 변환 (enum → double)
- 0은 포인터 타입이나 숫자 타입으로 변환된 0은 포인터 타입이나 숫자 타입으로 변환
- 포인터는 void 포인터로 변환
- 유저 정의된 타입 변환으로 일치하는 함수를 찾는다.
위 과정을 통하더라도 일치하는 함수를 못 찾거나, 같은 단계에서 두 개 이상이 일치하는 경우 모호하다(ambiguous)고 판단하여 오류 발생시킵니다.
#include <iostream>
int Add(int x, int y) { return x + y; }
int main() {
int x = 5;
char c = 'A';
int num = Add(x, c); // 1단계에서 찾지 못해, 2단계로 넘어가서 오버로딩 적용
std::cout << num << std::endl;
}
int Add(int x, char y) 함수는 없기에, 1단계에서 2단계로 넘어갔습니다.
char → int 로 형변환 진행 후, 다시 찾기 때문에 이번에는 찾을 수 있었던 거죠.
// 모호한 오버로딩
// 적절한 예시가 없어서 코드를 인용했습니다.
#include <iostream>
void print(int x) { std::cout << "int : " << x << std::endl; }
void print(char x) { std::cout << "double : " << x << std::endl; }
int main() {
int a = 1;
char b = 'c';
double c = 3.2f;
print(a);
print(b);
// print(c); 같은 단계에 두 개 이상의 가능한 일치가 존재하기 때문에 오류
return 0;
}
print(c)의 경우, 1, 2단계를 넘어서 3단계까지 이르게 됩니다. 여기서 임의의 숫자 타입으로 변환되기에 double이 int, char로도 변환될 수 있게 됩니다.
그러면 void print(int x), void print(char x)와 일치하기 때문에 같은 단계에서 두 개 이상의 일치하는 경우가 생기게 되죠. 따라서, 오류가 난 것입니다.
728x90
반응형
'Languages > C++' 카테고리의 다른 글
[C++] 초기화 리스트(Initializer list), static (0) | 2022.02.09 |
---|---|
[C++] 복사 생성자(Copy constructor), 얕은 복사(Shallow Copy), 깊은 복사(Deep Copy) (0) | 2022.02.09 |
[C++] 생성자(Default Constructor) 사용 시 주의사항 (0) | 2022.02.08 |
[C++] 참조자(Reference) (0) | 2022.02.08 |
[C++] 이름공간(namespace) 사용 시 주의사항 (0) | 2022.02.07 |