매개변수의 기본값 (Default parameters) 본문
매개변수의 기본값 (Default parameters)
Default parameter는 기본값이 제공된 함수 매개 변수이다.
사용자가 이 매개 변수의 값을 제공하지 않으면 기본값(default value)이 사용된다.
반대로 매개 변수의 값을 제공하면 사용자 제공 값이 기본값 대신 사용된다.
어떤 값을 출력하는 함수를 하나 만들어보자.
이때 x에 입력을 넣지 않으면 0을 출력해주세요라는 의미로
이렇게 넣어줄 수 있다.
이것을 default parameter 혹은 optional parameter 혹은 default argument라고 부른다.
default값을 1024로 바꿔서 실행시켜보자
이번에는 다시 기본값을 빼보자.
기본값이 필요한 것이다.
Multiple default parameters
함수는 디폴트 매개 변수를 여러개 가질 수 있다.
여기도 x,y,z 모두 기본값을 넣어줄 수 있고
두 개만 넣어줄 수도 있고 한 개만 넣어줄 수도 있다.
기본값이 오른쪽에 있을 때는
그 왼쪽에 있는 변수도 기본값을 넣을 수 있다.
그런데 예를 들어 가운데 있는 매개변수는 기본값이 있는데
가장 오른쪽에 있는 매개변수가 기본값이 없다면
모든 default parameter는 오른쪽부터 지정해야 한다.
세 개 모두 기본값이 있는 경우를 한번 해보자.
argument가 아무것도 안 들어간 경우에는 10, 20, 30 이 나왔고
x 하나만 넣어줄 경우에도 100나오고 나머지도 기본값으로 잘 나온다
다른 나머지들도 예상한대로 잘 나왔다.
Default parameters can only be declared once
여기서 주의할 점이 있다.
declaration과 definition을 분리하는 경우가 있다.
특히 위에가 헤더 파일로 갈 때가 많다.
객체지향 프로그래밍하시면 대부분은 다 헤더로 간다.
그럴 경우에는 기본 값 설정을 둘 중에 하나에서만 해줘야 한다.
여기에 기본값이 이렇게 들어있을 때는 밑에는 빼줘야 한다.
지금 이 상태에서 빌드를 해보면
위에 declaration 선언에 기본값이 들어가 있다면
밑에서는 이렇게 뺴줘야 한다.
왜냐하면
z가 기본값이 위에서는 30인데 밑에서는 300일 수도 있다.
그렇다면 둘 중 어느 것을 따라야하는데 아주 난감한 일이 벌어진다.
이런 모호한 문제를 아예 원천봉쇄하기 위해서 둘 중에 하나만 하게 되어있다.
반대로 definition에서 default값을 남겨두고 declaration에서 뺄 수도 있다.
그것은 선택하기 나름이다.
보통은 헤더파일에있는 declaration에 둔다
왜냐하면 프로그래머들이 함수가 어떤 구조로 되어있는지를 보고자 할 때에는
함수의 입력과 출력이 뭔지를 보려고 하는 것이다.
그렇기 때문에 헤더 파일에 있는 declaration 들을 먼저 보게 되어있다.
그때 기본 값이 뭔지 바로 눈에 들어와야 편하다.
만약에 헤더 파일에 있는 declaration에는 기본값이 없었는데
실제로 사용하려고 보니까 기본값이 나온다고 하면 아무래도 당황하게 된다.
그것보다는 헤더파일에 있는 declaration에 기본값들이 정의가 되어있는 것이 좋다.
다시 정리하자면
선언된 후에는 디폴트 매개변수를 다시 선언할 수 없다.
즉, 전방 선언과 함수 정의가 있는 함수의 경우,
default parameter는 전방선언이나 함수 정의 둘 중 하나에서만 선언할 수 있는 것이다.
가장 좋은 방법은 전방 선언이 다른 헤더 파일에 있는 경우
함수 정의가 아닌 전방 선언에서 default parameter를 선언하는 것이다.
foo.h :
#ifndef FOO_H
#define FOO_H
void print(int x, int y = 10);
#endif
main.cpp :
#include "foo.h"
#include <iostream>
void print(int x, int y)
{
std::cout << "x: " << x << '\n';
std::cout << "y: " << y << '\n';
}
int main()
{
print(5);
return 0;
}
위의 예제 main.cpp의 #include "foo.h"는 default parameter를 정의하는 전방 선언을 하고 있기 때문에
print() 함수를 가지고 있으므로
main.cpp의 print() 함수 정의에서는 default parameter를 사용할 수 없다.
Default parameters and function overloading
디폴트 파라미터가 있는 함수를 오버로딩할 수 있다.
다음 예제를 보자.
#include <string>을 사용하겠다.
void print(std::string str) {} 함수를 하나 만들고
void print(char ch = ' ') {} 를 만들었다.
이때 char ch = ' ' 라는 default parameter를 가지고 있다.
그래서 main()에 print(); 그냥 빈 파라미터를 두게 되면
당연히 char타입의 파라미터가 들어가 있는 오버로딩 함수를 선택할 것이다.
조금 더 난감한 경우를 보여드리자면
밑에 있는 print 함수에는 y에 default값이 들어있다.
이때 main()에서 print(10)을 넣어주고 빌드해보면 모호하다고 에러가 뜬다.
여기에 default값이 있을 때는 위에 print 함수와 굉장히 헷갈리게 되는 것이다.
그래서 y에 있는 default값을 제거해버리면
하지만 y에 default값을 넣고 싶다면
이렇게 앞에 deafult값이 없는 변수만 갖고 있는 다른 함수를 오버로딩할 수가 없다.
그래서 default값이 함수 오버로딩하는 데에도 영향을 준다.
프로그래밍을 하다 보면 api 형태로 제작을 하는 경우가 많아지고
옵션이 많아지고 당연히 매개변수가 늘어나는 경우가 많다.
그럴 때 default값은 유용하게 사용할 수 있다.
로고 파일을 저장할 때 파일 네임을 기본값으로 logo.txt로 하고 싶다거나
게임 개발을 할 때 fps를 최소 30은 되었으면 좋겠다는 의미로 default값을 30을 넣어준다던가
이런 식으로 뭔가 설정을 할 수 있는 일이 많이 있다.
유용한 기능이다.
다만 몇 가지 주의할 점이 있다는 것만 기억해두고 사용하면 편하게 사용할 수 있을 것이다.
'💘 C++ > 함수' 카테고리의 다른 글
스택과 힙 (Stack and Heap) (0) | 2022.08.15 |
---|---|
함수 포인터 (Function pointer) (0) | 2022.08.08 |
함수 오버로딩 (Function Overloading) (0) | 2022.08.06 |
인라인 함수 (Inline Functions) (0) | 2022.07.31 |
다양한 반환 값들(값, 주소, 참조, 구조체, 튜플) Returning values (0) | 2022.07.29 |