- 함수 중복 정의(function overloading)
C언어에서는 같은 이름을 갖는 함수를 정의할 수가 없었습니다. C++에서는 특정 조건을 만족하게 하는 경우 같은 이름을 갖는 함수를 중복해서 정의할 수 있습니다. C++에서는 컴파일 과정에서 사용자가 정의한 코드를 전개하는 과정에서 사용자가 정의한 함수명을 매개 변수 리스트에 따라 유일한 이름의 함수명으로 결정하는 함수 부호화(코드화) 과정이 진행됩니다. 그리고 함수를 호출하는 부분은 가장 적절한 매개 변수를 갖는 함수가 호출될 수 있게 연결(함수 이름 Mangling)해 줍니다. 이러한 이유로 C++에서는 사용자가 정의한 함수를 호출할 때 사용하는 이름을 함수명이라고 부르는 것 보다 메서드 명이라 부르는 게 좀 더 정확한 표현입니다. 즉, 정의하는 것은 함수이고 이를 호출할 때 사용하는 이름은 메서드 명이라 할 수 있습니다.
Demo.cpp - 함수 중복 정의 예 |
#include <iostream> using std::cout; using std::endl;
int GetMax(int a,int b) { if(a>b) { return a; } return b; } char GetMax(char a,char b) { if(a>b) { return a; } return b; } void main() { cout<<GetMax(2,3)<<endl; //int GetMax(int a, int b);로 연결 cout<<GetMax('a','b')<<endl; //char GetMax(char a,char b);로 연결 } |
함수 중복 정의는 결국 C++ 컴파일러의 전개과정에서 유일한 이름의 함수명으로 변경되고 호출부의 코드도 인자가 가장 적절한 함수로 연결되는 것입니다. 그렇다고 모든 경우에 함수 중복 정의가 가능하지는 않습니다. 컴파일러에서 호출하는 메서드명을 어떠한 함수를 호출하는 것인지 결정할 수 있어야 함수 중복 정의가 가능합니다. 다음의 예의 경우 어떻게 동작할지 생각해 보세요.
Demo.cpp – 리턴 형식만 다른 경우 함수 중복 정의가 안 됨 |
#include <iostream> using std::cout; using std::endl; void Foo() { cout<<"void Foo()"<<endl; } int Foo() { cout<<"int Foo()"<<endl; return 0; } void main() { Foo(); } |
위의 예를 보면 두 개의 함수는 리턴 형식을 제외한 나머지 부분에서 모두 같습니다. 함수를 호출하면 리턴 값을 반드시 사용해야 하는 것이 아니므로 리턴 형식만 다른 경우에는 함수 중복 정의를 할 수 없습니다.
[그림 1.6]
[그림 1.6]을 보면 알 수 있듯이 반환 형식만 다른 경우 함수 중복 정의가 되지 않음을 알 수 있고 함수 이름 연결도 안 된다는 것을 알 수 있습니다. 이 외에도 함수 호출부에 있는 코드를 어느 함수로 연결(함수 name mangling)할지 판단하기 모호한 경우에도 에러가 발생합니다.
입력 매개 변수 리스트 중에 value인지 Reference인지만 다른 경우도 함수 이름 연결이 모호함 |
#include <iostream> using std::cout; using std::endl; void Foo(int &a) { cout<<"void Foo(int &a)"<<endl; } void Foo(int a) { cout<<"void Foo(int a)"<<endl; } void main() { int a=0; Foo(3); Foo(a); } |
예제 코드에서 Foo(a); 호출 구문을 제외해서 컴파일하면 아무런 오류도 발생하지 않습니다. 하지만 이를 포함하면 모호하다는 오류를 발생시킵니다. 결론적으로, 위의 예제에서 void Foo(int &a)를 호출할 방법이 없습니다. 함수를 정의만 하고 호출 구문이 없이 컴파일할 수 있다고 끝난 것이 아닙니다. 사용할 수 없는 함수를 정의하는 것은 아무런 의미도 없어서 위의 경우도 잘못된 함수 중복 정의라 할 수 있습니다.
마지막으로 묵시적 형 변환 연산 우선순위가 같은 경우에 함수 이름 연결에서 모호하다는 오류가 발생합니다. 예를 들어 int형의 경우 unsigned int 형과 long형과의 묵시적 형 변환이 가능한데 묵시적 형 변환 우선순위가 같습니다. 이렇게 세세한 문법을 모두 기억할 수 있으면 좋겠지만, 여러분이 프로그래밍하면서 사용하는 형식에 대해 위배하지 않으려고 노력한다면 큰 문제가 없을 것으로 생각합니다.
[그림 1.7]
(모든 동영상 강의는 무료입니다.)
'언어 자료구조 알고리즘 > Escort C++' 카테고리의 다른 글
[C++] 2.2.1 접근 지정자 (0) | 2016.04.15 |
---|---|
[C++] 2. 1 캡슐화란? (2) | 2016.04.15 |
[C++] namespace (0) | 2016.04.15 |
[C++] 매개 변수명이 없는 입력 매개 변수 (0) | 2016.04.15 |
[C++] 디폴트 매개 변수 (0) | 2016.04.15 |
[C++] 1. 2 클래스를 제외한 C언어와 다른 문법 사항 (레퍼런스 변수) (0) | 2016.04.15 |
[C++] 1. 2 클래스를 제외한 C언어와 다른 문법 사항(태그명, 변수 선언 위치) (0) | 2016.04.15 |
[C++] 1. 2 클래스를 제외한 C언어와 다른 문법 사항(bool 형식의 제공) (0) | 2016.04.15 |
[C++] 1. 2 클래스를 제외한 C언어와 다른 문법 사항 (const 포인터, void 포인터) (0) | 2016.04.15 |
[C++] 1. 2 클래스를 제외한 C언어와 다른 문법 사항 (열거형) (2) | 2016.04.15 |