오버로드는 스타크래프트가 아니라
철자가 다르다.
Lord - Load
아무튼
객체지향언어의 특징인 다형성을 위해 오버로딩이 나왔다.
알아보자
함수 오버로딩이란
하나의 함수가 여러가지 형태를 가지는 것이다.
여기서 여러가지 형태란
하는 일은 같지만 사용하는 매개변수가 다를 때를 말한다.
예를 들어
눈이 온다.
눈이 아프다.
에서 눈이 모양은 같지만 다른 의미로 사용되는 것과 비슷하다.
다시 말하자면 함수 오버로딩은 매개변수에 따라 달라진다.
만약에 두 함수가 같은 개수, 같은 데이터형의 매개 변수를 가지고, 매개변수의 순서까지 동일하다면
두 함수의 시그니처는 같다고 한다.
++ 이 때는 매개변수의 이름은 달라도 상관없다. (int x든 int y든 변수의 이름은 중요치 않다)
C++에서는
서로 다른 시그니처를 가지고 있는 함수들을 같은 이름으로 정의할 수 있다.
-> 이것이 바로 오버로딩
이 때 얘네들은 서로 매개변수 개수와 종류가 다르다( 시그니처가 다르니까 )
예를 들어보자
5가지 모두가 print라는 같은 함수이름을 가지고 있는데도..?
오류가 나지 않는다.
void print(const char *str, int width);
void print(double d, int width);
void print(long l, int width);
void print(int i, int width);
void print(const char *str);
각각 모두 정상적으로 작동할 것이란 이야기다.
즉, double 변수가 오면 2번째 print에 대한 함수 수행이
int 변수가 오면 4번째 print에 대한 함수 수행이 이루어질 것이라는 말이다.
**C++은 고맙게도 대응하는 원형이 없음에도 데이터형 변환을 시도하여 어떻게든 대응할 수 있도록 노력한다.
예를 들어서
unsigned int year = 2021;
print(year, 5);
위에서는 unsigned int에 대한 함수가 없었지만
데이터형을 바꿔서 print함수가 실행되게 만들 것이다.
하지만 double, int, long 중에 어떤 것으로 데이터형 변환을 해야할 지 모르기 때문에
사용자의 실수라고 생각하고 컴파일러에서 에러를 일으킨다.
즉, 컴파일러가 어떤 것인지 구분 못할 경우에는 에러를 일으킨다.
다른 예를 보자
double cube(double x);
double cube(double &x);
과연 이것이 오버로딩일까?
컴파일러 입장에서 생각해보면
x는 double 자료형의 값이고
결국 &x도 해당 포인터가 가리키는 값이 double형이다.
-> x를 참조 변수로 쓰겠다는 말이고 결국 double형의 데이터를 매개변수로 받겠다는 것이다.
결국 같은 시그니처라는 말이다.
그래서 컴파일러가 에러를 쓰로잉한다.
또한 특징이 있다면 const와 const가 아닌 변수는 구별한다.
-> 즉, const인 것을 주면 해당 함수가 const로 오버로딩된 함수로 수행된다는 뜻이다.
이정도만 알면 됐고
함수 오버로딩의 핵심은
함수의 데이터형 자체가 아니라
시그니처라는 사실을 알아야 한다.
long g(int a, double b);
double g(int a, double b);
//위 2개는 서로 같은 시그니처라 오버로딩이 안된다.
반대로
long h(int a, float b);
double h(float a, float b);
서로 다른 시그니처이므로 공존할 수 있다.
마지막으로 오버로딩에 대해서 말하자면
분명 오버로딩은 같은 역할을 하지만 다양한 매개변수에 대해서 수행할 수 있어서 좋다.
다만 과용하면 안된다.
즉, 같은 역할을 하지 않는데도 오버로딩해서 사용한다면 의도치 않은 결과를 볼 수 있다.
또한 이전에 배운 디폴트 매개변수를 사용할 수도 있다.
[프로그래밍언어(Programming Language)/C || C++] - C++문법/ 디폴트 매개변수, Default Parameter
다시 말해서 처음에 함수가 같은 역할을 하지만 다른 매개변수를 받고싶을 때는
먼저 디폴트 매개변수를 사용할 수 있는지 생각해보자
만약 된다면
디폴트 매개변수를 사용하면 함수를 하나만 작성할 수도 있고
수정할 때에도 하나만 수정하면 된다.
하지만 서로 다른 데이터형의 매개변수를 요구하거나 디폴트 매개변수로 해결할 수 없다면
그 때 오버로딩을 사용하면 된다.
하지만 연산자함수를 정의하고 싶을 때는??
즉, 우리가 보는 기호들 +, -, * 같은 것을 오버로딩하고 싶을 때는 조금 다르게 쓴다.
일반적으로 이런 기호를 바로 함수이름으로 쓸 수 없어서
operator라는 키워드를 쓴다.
예를 들어서 '+'로 시간을 계산하고 싶다??
(물론 Time 클래스를 내가 만들었다.)
const Time operator +(const Time &other) const{
Time t;
t.sec = sec + other.sec;
t.min = min + other.min;
t.hour = hour + other.hour;
t.min += t.sec/60;
t.sec %= 60;
t.hour += t.min/60;
t.min %= 60;
return t;
}
'프로그래밍 지식 > C++' 카테고리의 다른 글
C++ 문법 / 기본 수학 연산 함수 (0) | 2021.12.02 |
---|---|
C++문법/ 타입캐스팅, 캐스트 연산자 (0) | 2021.12.02 |
C++문법/ 함수 매개변수에서 * 과 &의 차이 ★★★★★ (0) | 2021.11.30 |
C 문법/ 소스파일부터 실행파일까지, From source To exe (0) | 2021.11.30 |
C++문법/ 디폴트 매개변수, Default Parameter (0) | 2021.11.30 |