C언어와는 조금 다르게 C++의 함수는 조금 더 특별한 기능이 추가되었습니다. 뭐가 다를까요?
1. C언어에서는 함수명이 같으면 컴파일 에러가 나지만 C++에서는 함수명이 같아도 매개변수의 자료형, 갯수가 다르다면 같은 함수명을 쓸 수 있습니다. 이것이 함수 오버로딩(overloading)이라고 하지요.
2. C언어에서는 함수 인자에 default값을 줄 수 없습니다. 하지만 C++에서는 사용자가 매개변수에 값을 넘겨주지 않으면 자동으로 dafault값이 지정됩니다.
3. C언어에서와 다르게 참조자(reference)가 등장합니다. 변수의 별칭이라고나 할까요?
4. 함수의 호출시간을 줄이고자 inline함수가 등장합니다. inline함수는 일반 함수와는 다르게 함수의 호출부에 코드를 직접 삽입함으로써 함수가 호출되는 과정이 없습니다. 그러니까 실행속도가 일반함수 호출하는 것보다 빠르지요.
대략적인 설명은 여기까지 하겠습니다. 이제 하나하나 자세하게 살펴보도록 합시다.
1. 함수오버로딩(Overloading)
함수오버로딩은 개념이 꽤나 간단합니다. 예를 들어 두 수를 더해서 반환하는 sum이라는 함수가 있다고 합시다. 우리는 정수형, 실수형 모두 sum이라는 함수로 이름을 짓고 싶습니다. 왜냐면 자료형만 다를뿐 같은 기능을 하기 때문이죠. 이렇게 오버로딩의 개념이 등장합니다.
아래의 코드가 오버로딩을 보여줍니다.
#include <iostream>
using namespace std;
int sum(int a, int b) {
return a + b;
}
double sum(double a, double b) {
return a + b;
}
int sum(int a, int b, int c) {
return a + b + c;
}
double sum(double a, double b, double c) {
return a + b + c;
}
int main(void) {
cout << sum(10, 20) << endl;
cout << sum(10.1, 20.1) << endl;
cout << sum(10, 20,30) << endl;
cout << sum(10.1, 20.1,30.1) << endl;
}
함수의 인자들이 자료형이 다른 것도 있고, 인자의 갯수가 다른 것이 있습니다. 함수의 이름은 같은 것을 알 수 있네요.
여기서 주의해야할 점은 반환형이 달라도 오버로딩이 되지 않습니다. 항상 매개변수의 타입 또는 갯수가 달라야 오버로딩이 된다는 것을 알아두세요.
2. default 인자 값
인자를 전달하지 않으면 default로 지정된 값으로 인자 변수가 초기화됩니다. 이것도 역시 어렵지 않습니다.
#include <iostream>
using namespace std;
int sum(int a, int b = 10) {
return a + b;
}
int main(void) {
cout << sum(20) << endl;
cout << sum(20, 20) << endl;
}
함수의 인자 갯수는 2개이지만 sum(20)이라는 호출이 가능한 이유는 b가 10으로 default 값을 사용하기 떄문입니다. 또는 보통의 함수 호출과 같이 인자를 2개 주어서 사용할 수도 있습니다.
디폴트 인자값을 사용할때 주의할 점이라고 한다면 디폴트 인자값은 항상 오른쪽부터 왼쪽으로 써줘야한다는 것입니다.
int sum(int a, int b = 10,int c) {
return a + b + c;
}
int sum(int a, int b = 10, int c = 20) {
return a + b + c;
}
첫번째 처럼 중간이 디폴트 인자값이 있다면 오류가 나게되고 항상 밑의 함수처럼 오른쪽부터 왼쪽으로 디폴트값을 써줘야한다는 겁니다.
3. 참조자(Reference)
참조자는 C++에서 새롭게 등장한 기능입니다. 변수의 별명이라고 생각하면 될 것 같습니다. 우리가 어떤 사람을 부를때도 별명을 부르곤 하잖아요? reference를 사용할땐 &를 사용하여 참조자라는 것을 알려줍니다.
예를 들어 이렇게 사용하죠.
int a=100;
int &b=a;
이렇게 b는 a와 같은 데이터를 가리키며 주소 역시 같습니다. 마치 포인터처럼요.
이것을 함수에 사용하게 되면 call-by-reference를 구현할 수 있게 됩니다. 우리는 call-by-reference를 C언어에서 포인터로 시험해봤지요.
이제 참조자를 통해서 구현해보도록 합시다.
#include <iostream>
using namespace std;
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
int main(void) {
int a = 100;
int b = 200;
cout << "a:" << a << ",b:" << b << endl;
swap(a, b);
cout << "a:" << a << ",b:" << b << endl;
}
실행시켜보면 아래와 같이 값이 바뀐 것을 알 수 있습니다. a와 b에 주소값을 swap함수에 넘기지 않고 말이죠.
결과
a:100,b:200
a:200,b:100
계속하려면 아무 키나 누르십시오 . . .
이 같이 참조자는 크기가 큰 구조체나 데이터를 매개변수로 전달할 때 유용합니다.
4. inline 함수
보통의 함수 호출 과정은 다음과 같습니다.
스택에 다시 돌아갈 주소를 저장. 매개변수 전달 -> 스택에 지역 변수 할당 -> 함수 실행 -> 반환값 전달 -> 다시 돌아갈 주소로 이동
함수의 실행부분이 꽤나 길다면 뭐 호출하는 시간은 신경쓰지 않아도 되지만 함수의 실행부가 짧지만 자주 호출된다면 호출되는 시간을 무시할 순 없겠죠.
inline함수는 함수의 호출시간을 줄여 보다 더 빠른 성능을 내기 위함입니다. inline함수는 함수 호출부에 함수 정의 부분을 직접 삽입하여 호출하는 방식으로 매크로 함수와 비슷합니다. 하지만 매크로 함수를 쓰면 괄호의 늪에 빠질 수도 있죠..
인라인 함수는 간단합니다. 기존의 함수를 선언하거나 정의하는 부분에 inline 키워드만 붙여주면 되니까요.
inline키워드는 선언 또는 정의하는 부분에 한번만 선언해주어도 됩니다.
#include <iostream>
using namespace std;
inline int sum(int, int);
int sum(int a, int b) {
return a + b;
}
int main(void) {
int sumValue;
sumValue = sum(10, 20);
cout << sumValue << endl;
}
실제 이 코드는 이렇게 동작하게 됩니다.
#include <iostream>
using namespace std;
int main(void) {
int sumValue;
{
int a = 10; int b = 20;
sumValue = a + b;
}
cout << sumValue << endl;
}
정말 단지 inline함수의 내용이 코드에 직접 삽입되는 형태지요.
지금까지 C++에서 함수의 특징에 대해서 알아보았습니다. 딱히 어려운건 없었죠?
'언어 > C++' 카테고리의 다른 글
[C++] STL vector 개념과 정리 - 사용법 파헤치기 (0) | 2022.03.24 |
---|---|
[C언어/C++] lower_bound(하한)과 upper_bound(상한)을 C와 C++에서 사용하는 예제 코드 (0) | 2021.03.23 |
[C++] new,delete 키워드와 오버라이딩(Overriding),다형성(Polymorphism)의 개념과 virtual키워드 사용방법, 객체의 this 포인터 개념 (0) | 2021.03.18 |
[C++] 클래스와 상속(Inheritance)의 개념과 사용법, 캡슐화의 이해 (0) | 2021.03.16 |
[C++] C언어와의 차이 namespace (2) | 2018.10.02 |