객체지향프로그래밍(6) - 함수 오버로딩, 생성자 오버로딩

함수 오버로딩과 생성자 오버로딩 이해

Featured image

🔚 짧게 하는 복습

✅ 1. 디폴트 생성자가 무엇인지 안다.

✅ 2. 매개변수를 통한 생성자를 만들 수 있다.

✅ 3. 생성자 리스트를 통한 생성자를 만들 수 있다.

혹시 기억이 안 난다면, 다시 돌아가자


저번 시간에는 생성자와 생성자 리스트를 다루는 법을 배웠다.

특히, 이름을 입력 받아서 포켓몬을 객체화하는 프로그램을 생성했다.

그럼 저번 시간의 코드에서 확장하여, 매개변수 없이 호출하면 이름이 unknown인 채 생성되고, 이름을 입력하면 그 이름으로 설정하는 코드를 생각해보자.

지금까지 C언어 강의를 충실히 따라온 분들이라면 자연스럽게 다른 이름의 생성자가 두 개는 필요하다는 것을 알 것이다.

왜냐하면, 한 함수는 매개변수가 없고 다른 함수는 이름이라는 매개변수가 있기 때문이다.

그리고 이런 경우에는, 같은 이름의 함수를 사용할 수 없기 때문이다.

그런데 오늘 우리가 배울 기능은 이런 한계를 극복하고, 지금까지의 함수 개념을 제대로 확장할 것이다.


함수 오버로딩이란?

함수 오버로딩이란 같은 이름의 함수가 다른 매개변수를 가지는 것을 말한다.

우선 아래의 예제를 보자.

이런 기능이 왜 필요한지 모르겠다면, 본인이 공학용 계산기 모듈을 만든다고 생각해보자.

두 변수 더하기 모듈을 만든다고 했을 때, 어떠한 자료형이든 return a+b를 하는 것은 명백히 같다.

그런데 a+b를 만들 때 int_add, double_add, long_long_add 등을 만들어야 한다고 하면, 우리가 싫어하는 코드 중복이 발생하기 마련이다.

그리고 이는 객체지향에서 중시하는 가치 중 유지보수에도 방해가 된다.

매개변수 자료형마다 다른 함수에 네이밍을 하게 되면, if 문 등으로 매번 구분해서 함수를 실행해야 한다.

이렇게 되면 전체 코드에서 특정 부분을 수정해야 할 때, 전체의 if 문을 훑어봐야 하는 불편함이 생긴다.

생성자에 대해 이야기를 하다가 함수 오버로딩이 갑자기 왜 튀어나오나 싶겠지만, 함수 오버로딩생성자 오버로딩이라는 기능으로 확장된다. (함수 오버로딩은 생성자 오버로딩을 위한 것으로 오해할 수 있지만, 함수 오버로딩 자체도 중요한 기능이고 많이 사용된다.)


생성자 오버로딩이란?

아까 말한 같은 이름의 생성자가 매개변수의 개수와 종류만 다른 경우, 바로 함수 오버로딩이 필요한 순간이다.

생성자도 함수이기 때문에, 오버로딩이 가능하다.

위에서 요구된 상황을 직접 구현해보자.

pokemon() : name("unknown"), type(0), hp(0), attack(0), defend(0), mobility(0), skill({0,0}) {} //디폴트 생성자

pokemon(std::string _name) : name(_name), type(0), hp(0), attack(0), defend(0), mobility(0), skill({0,0})   {} // 이름 변수 생성자

//... 생략

int main() {
	pokemon pomon = pokemon("브케인"); // 생성자 리스트를 이용한 생성자
	pokemon pomon2 = pokemon();

	pomon.get_info();
	pomon2.get_info();
}

생성자 리스트와 생성자 오버로딩을 통한 코드로, 위는 대부분의 일반적인 상황, 아래는 특정한 상황에 대한 생성자를 만들었다.


결과

이름 : 브케인
타입 : 0
체력 : 0
공격력 : 0
방어력 : 0
이동속도 : 0
스킬 위력 : 0
스킬 명중률 : 0
이름 : unknown
타입 : 0
체력 : 0
공격력 : 0
방어력 : 0
이동속도 : 0
스킬 위력 : 0
스킬 명중률 : 0

디폴트 생성자오버로딩을 통한 생성자 모두 잘 작동하는 것을 볼 수 있다.


실생활에서의 생성자 오버로딩

보통 생성자를 오버로딩하는 경우는, 대부분의 상황에 사용할 기본 값을 설정하고 싶기 때문이다.

우리가 사용하는 대부분의 장치들은 ‘디폴트(기본)’ 상태가 정의되어 있다.

예를 들어, 숙박업소의 TV는 처음 틀면 특정 채널이 나오고 게임에서 캐릭터를 만들면 처음 레벨은 1레벨로 설정이 되어있다.

하지만 어떤 특정한 설정을 한다면, 기본값을 바꿀 수 있다.

즉, 이러한 실제 세계를 닮고자 하는 객체지향의 관점에서 생성자 오버로딩은 필수인 것이다.


오버로딩의 장점과 단점

오버로딩의 가장 큰 장점은 코드 일관성 증가이다.

같은 내용의 함수가 매개변수만 다를 때, 하나의 용도하나의 이름을 가진 함수만 사용되니 일관성이 증가된다.

이는 굉장히 큰 장점이지만, 동시에 단점으로도 돌아온다.

오버로딩이 많아질 경우, 어떤 함수가 호출되는지 바로 이해하기 힘들어진다.

가독성의 손해는 결국 유지보수의 손해이고, 유지보수의 용이라는 객체지향 프로그래밍에서 원하는 가치와 멀어진다.

그리고 마지막으로, 오버로딩의 규칙(읽어볼 거리 참고)을 완벽하게 이해하지 않는다면 의도치않은 형변환을 통해 예상하지 못한 오류가 발생할 수 있다.

아래의 잘못된 코드를 보자. 5번째 add부터는 무엇이 실행될지 예측도 안된다.

이런 코드를 작성하지 않도록, 오버로딩의 규칙을 잘 이해하도록 하자.


✅ 1. 오버로딩이 무엇인지 알고, 장단점이 무엇인지 안다.

✅ 2. 생성자 오버로딩, 생성자 리스트를 사용할 줄 안다.

✅ 3. 읽어볼 거리를 통해, 오버로딩의 우선 순위를 이해한다.

⚠️ 오버로딩은 객체지향 프로그래밍에만 국한되지 않는다. 일반적으로 선언되는 전역범위 함수에서도 사용될 수 있다.

⚠️ 오버로딩의 우선 순위를 숙지하는 것은 매우 중요하지만, 모호하게 코딩하지 않는 것이 훨씬 더 중요하다.

💣 과제, 없음

🔜 더 공부해보기,

읽어볼 거리(1) - 오버로딩의 우선 순위 (꼭 읽어보는 것을 추천)