C++/C++ : Study

OOP - (6) 생성자 오버로딩

더블유제이플로어 2024. 10. 28. 00:19

(Summary) Constructor Overloading

◆  생성자 오버로딩 개요

◆  생성자 초기화 리스트

◆  생성자 위임

◆  생성자 기본 매개변수


Overloading Contructor

◆  생성자 오버로딩

  ● 생성자는 오버로딩 가능
  ● 각자의 생성자는 고유해야 한다. (매개변수가 달라야 한다.)
        ☞ 함수 오버로딩과 동일한 규칙

생성자도 함수니깐 오버로딩을 할 수 있다.
매개변수가 함수마다 다르게 구현해야 한다.


어떻게 효율적으로 할 수 있을까?
효율적으로 코드를 작성할 수 있는지 계속 생각해야 한다.


중요한 Part이다.

◆  생성자 초기화 리스트

  ● 진짜(?) 초기화
  ● 이전의 생성자는 생성자 본체 (body) 내에 멤버 변수 값을 대입한다.
  ● 생성자 초기화 리스트를 사용할 경우 생성과 동시에 값이 지정된다.

생성할 때 쓰레기 값이 들어오니, 그 값도 막아주기 위해서 초기화 방법을 권장 방법대로 선언한다.
예를 들면 쓰레기 값이 들어오고 초기화가 하기 이전에 멤버 함수를 계산 등을 할 수 있기 때문이다.
(xp *=2; 컴파일러 에러는 나오지 않는다.)

xp 가 쓰레기 값에서 xp *=2; 가 동작한 것을 확인할 수 있다.

위와 같이 선언하게 되면
객체의 생성과 동시에 값이 지정이 된다.

그렇기에 선언 후에 변수에 계산 등을 하여도 문제 없이 적용된다.
항상 권장 방법처럼 생성자 초기화 방법을 사용해야한다.


Delegating Constructors

◆  생성자 위임

  ● 다양한 생성자의 오버로딩에 유사한 코드가 반복적으로 사용
  ● 오류의 가능성이 높아짐

  ● 생성자 위임을 통해 오류 가능성과 코드 반복을 줄일 수 있다.
        ☞ 다른 생성자를 멤버 초기화 리스트 위치에서 호출
        ☞ 생성자 멤버 초기화 리스트를 사용해서만 가능하다.

◆  생성자 위임을 사용하지 않는 기존 코드

	Player()
		:name{ "None" }, health{ 0 }, xp{ 0 }
	{ }
	Player(string nameVal)
		:name{ nameVal }, health{ 0 }, xp{ 1 }
	{
		xp *= 2;
	}
	Player(string nameVal, int healthVal, int xpVal)
		:name{ nameVal }, health{ healthVal }, xp{ xpVal }
	{ }

◆  생성자 위임을 사용한 코드

생성자를 호출할때 구현 되어있는 또 다른 생성자를 넘겨서 초기화 하는 방법이다.


Default Constructor Parameters

◆  생성자 기본 매개변수

  ● 생성자 또한 함수이므로, 기본 매개변수 사용 가능

class Player
{
public:
	Player(string nameVal = "None", int healthVal = 0, int xpVal = 0);
private :
	string name;
	int health;
	int xp;
};

Player::Player(string nameVal, int healthVal, int xpVal)
	:name{ nameVal }, health{ healthVal }, xp{ xpVal }
{ }
	Player empty; // None, 0, 0
	Player kim{ "Kim" }; // Kim , 0, 0
	Player hero{ "Hero", 100 }; // Hero, 100, 0
	Player enemy{ "Enemy", 1000,0 }; // Enemy, 1000, 0

인자가 없이 객체를 생성한 경우
Class Player에 보니 인자 없이 객체를 생성한 생성자는 없다.
하지만 Player(string nameVal = "None", int healthVal = 0, int xpVal = 0);
생성자 같은 경우 인자를 안 받으면
첫번째 인자는 None으로, 두번째 세번째 인자는 0으로 기본값으로 사용하도록 되어 있다.
함수의 기본 매개 변수에서 배운 내용이다.

그렇기 때문에 empty는 None, 0, 0 으로 초기화가 된다.

Player::Player(string, int, int)를 쓰니 Player empty; 가 선언이 되고
Player(string, int, int)함수가 Player Class 에서 private 로 선언되면
Player empty;는 컴파일러 에러가 난다.


(Summary) Constructor Overloading

◆   생성자 오버로딩 개요

  ● 매개변수가 다른 고유한 생성자들을 오버로딩

◆   생성자 초기화 리스트

  ● 본체에서 값을 대입하는 것이 아닌 생성과 동시에 값을 지정

◆   생성자 위임

  ● 다른 생성자를 초기화 리스트 자리에서 호출
  ● 생성자 초기화 리스트를 사용해서만 가능

◆   생성자 기본 매개변수

  ● 함수처럼 기본 매개 변수 사용 가능

생성자는 함수의 종류이기 때문에 함수처럼 기본 매개변수를 사용 가능하다.
다만, 생성자에 본체 안에 초기화를 하게 되면 문제가 있을 수 있다.
그렇기 때문에 생성과 동시에 값을 지정하는 초기화 리스트 문법을 사용하는게 좋다.

오버로딩을 하게 될 경우 작업마다 계속 코드로 작성해야하니 매우 귀찮고 실수 할 가능성이 있다.
그럴 땐 다른 생성자를 위임해서 사용한다.
초기화 리스트 자리에서 인자를 다 받는 함수에서 인자를 안받는 생성자 자리에서
초기화 리스트를 호출해서 재 사용성으로 사용할 수 있다.

클래스와 객체가 어떻게 동작하는지
클래스가 생성할때 소멸될때 생성자와 소멸자를 잘 사용할 줄 알아야 한다.


https://youtu.be/jCXPnkZ0LxQ?si=Hassw-QXK1VknTIT

생각보다 오래 걸렸지만, 앞으로는 빨리 학습해야겠다.