C++

15. Constructor & Destructor (1)

Kelvin의 게임개발 2024. 4. 3. 01:05
728x90
반응형

1. Constructor & Desturctor

 

생성자 (Constructor)는 특별한 멤버함수이다
생성자는 객체 생성시 호출되고 초기화에 유용하게 사용된다
생성자 이름은 클래스 이름과 같다 ex) Player 클래스의 생성자는 Player(), Player(int 32 Test)... 등등


생성자는 반환형은 없고 매개변수는 존재할 수 있으며 오버로딩 할 수 있다

(클래스는 오버로딩을 통해 많은 생성자를 가질 수 있다, 이 많은 생성자들은 각각 Unique해야 한다 (객체 생성시 어떤 생성자를 호출해야 할 지 알아야 하기 때문이다, 모호성을 가진다면 컴파일 에러가 발생한다)
 
소멸자는 (Destructor)는 특별한 멤버함수이다
소멸자 이름은 클래스 이름과 같고 앞에 ~이 붙는다 ex) ~Player()
소멸자는 객체 파괴 시 호출된다
소멸자는 객체당 1개씩만 존재해야 한다
소멸자는 반환형과 매개변수가 없다

명시적으로 생성자, 소멸자를 만들지 않으면 컴파일러가 기본 생성자, 소멸자를 호출한다 

class Player
{
private:
	string name;
	int health;
	int xp;

public:
	//생성자 이름은 Class이름과 동일하다
	//함수 오버로딩과 마찬가지로 생성자 오버로딩이 가능하다
	Player();
	Player(string name);
	Player(string name, int health, int xp);

	//소멸자 이름은 Class이름과 동일하며 ~가 앞에 붙는다
	~Player();
};
int main()
{
	
	Player P1; //No Arg Constructor Called
	Player P2("Kelvin"); //1 Arg Constructor Called
	Player P3("Kelvin", 100, 50); //3 Arg Constructor Called
	
	Player P4{"Kelvin", 100, 50}; //생성자도 변수 초기화와 마찬가지로 { }를 이용하여 초기화 가능
	
	Player* TempP1 = new Player; //No Arg Constructor Called
	Player* TempP2 = new Player("Jacob"); //1 Arg Constructor Called
	Player* TempP3 = new Player("Jacob", 50, 10); //3 Arg Constructor Called

	delete TempP1;
	delete TempP2;
	delete TempP3;
	//TempP1, TempP2, TempP3의 소멸자 호출


	return 0;

	//P1, P2, P3의 소멸자 호출
}

 

 

2. Default Constructor

 

기본 생성자는 매개변수를 가지지 않는 생성자를 의미한다 (no-args constructor)

 

프로그래머가 생성자를 명시적으로 생성하지 않으면 컴파일러가 자동으로 기본 생성자를 호출한다


기본 생성자 내부에서 따로 멤버 변수를 초기화 해서 사용할 수 있다 (Garbage Data방지 신경쓰자)

 

단 이때 생성자를 명시적으로 작성을 하면 컴파일러는 기본 생성자를 생성하지 않는다 ex) 인자를 1개를 넘기는 생성자만 만들고 기본 생성자를 만들지 않으면 Player P1;과 같이 기본 생성자를 호출하여 객체 생성이 불가능함 (컴파일 에러)

 

기본 생성자를 명시적으로 만들면 컴파일러가 제공하는 기본 생성자가 아닌 프로그래머가 명시적으로 생성한 기본 생성자가 호출된다

 

class Player
{
private:
	string name;
	int health;
	int xp;

public:
	//명시적으로 기본생성자 생성
	Player();

	~Player();
};
Player::Player()
{
	cout << "No Arg Constructor Called" << endl;
	
	//기본 생성자에서 멤버 변수 초기화
	name = "Kelvin";
	health = 100;
	xp = 30;
}
int main()
{
	Player P1;

	return 0;
}

 

 

 

3. Constructor Initialization List

 

Constructor Initialization List란 생성자 초기화 리스트를 의미한다


이제까지 생성자 내부에서 데이터를 초기화해서 사용했다 이는 정확히 말하면 초기화가 아닌 이미 생성된 데이터에 값을 할당하는 것이다


정확한 초기화란 멤버 데이터를 생성자가 실행되기 전에 값으로 초기화 하는것을 의미한다
 
생성자 초기화 리스트로 이러한 정확한 초기화가 가능하다
 
생성자 초기화 리스트는 생성자 옆에 :을 작성하고 그 뒤에 원하는 멤버 데이터를 초기화 해주고 { }로 마무리 해준다
 
생성자 초기화 리스트에서 초기화 순서는 :옆에 리스트 순서가 아닌 class 내부의 선언 순서에 따라 초기화 된다


생성자 초기화 리스트는 모든 생성자에서 다 가능하다

class Player
{
private:
	string name;
	int health;
	int xp;

public:
	Player();

	Player(string InName);
};
//생성자 초기화 리스트 (생성자가 호출되기 전에 멤버 데이터를 초기화 함)
Player::Player() : name{"None"}, health{0}, xp{100}
{
	cout << xp << endl; //100출력

}

//모든 생성자에서 생성자 초기화 리스트로 멤버 데이터 초기화가 가능하다
Player::Player(string InName) : name{"Kelvin"}, health{100}, xp{300}
{

}

 

 

4. Delegate Constructor

 

생성자는 다른 생성자에 위임하여 사용이 가능하다
 
클래스에 여러 개의 생성자가 있는 경우 각 생성자의 기능이 중복되는 경우가 많다
이러한 중복 코드를 방지하기 위해 Delegate Constructor (생성자 위임)을 해주어야 한다

생성자 뒤에 : 을 붙히고 그 뒤에 원하는 생성자{매개변수}로 호출하여 사용이 가능하다

 

이때 클래스 인스턴스가 생성되면 위임한 생성자 (:뒤에 호출한 생성자)가 먼저 호출된 후에 위임 받은 생성자가 호출된다
 
위임한 생성자에 생성자 초기화 리스트 및 다른 코드가 있다면 같이 위임된다

//Player(string InName) 생성자를 위임함 -> Player(string InName)가 호출되고 그 뒤에 Player() 생성자가 호출됨
//콘솔 결과는 Jacob, 500이 나오게 된다 (Player(string InName)의 생성자 초기화 리스트, 코드가 같이 위임되었기 때문이다)
Player::Player() : Player{"Kelvin"}
{
	cout << xp << endl;

}

Player::Player(string InName) : name{"Jacob"}, health{1000}, xp{500}
{
	cout << name << endl;
}

 

 

5. Constructor Parameter and Default Value

 

함수의 매개변수가 default값을 가질수 있는것과 마찬가지로 생성자의 매개변수도 default value값을 가질 수 있다

 

원래는 생성자의 매개변수 개수를 맞추지 않고 사용하면 컴파일에러가 발생하지만 생성자 매개변수에 default value값이 존재하면 default value값이 존재하는 매개변수는 인자로 넘기지 않아도 사용이 가능하다

 

class Player
{
private:
	string name;
	int health;
	int xp;

public:
	//생성자도 함수와 마찬가지로 매개변수가 default value를 가질 수 있다
	Player(string InName = "Empty", int InHealth = 1000, int InXp = 100);
    
    
	Player(); //이때 매개변수를 가지지 않는 생성자가 있다면 컴파일러 입장에서 어떤 생성자를 호출해야 할지 모호하기 떄문에 컴파일 에러를 발생시킨다
};
Player::Player(string InName, int InHealth, int InXp) : name{InName}, health{InHealth}, xp{InXp}
{
	cout << name << endl;
	cout << health << endl;
	cout << xp << endl;
}
int main()
{
	//원래는 3개의 매개변수를 가진 생성자에 0개, 1개의 인자만 넘겨서 사용했기 때문에 컴파일 에러가 발생해야 하지만 default value가 있기 때문에 정상 동작함
	Player Empty; //생성자 매개변수의 default값인 Empty, 1000, 100이 나오게 됨
	//이때 Player()도 있다면 Player()을 선택해야 할지, Player(string InName = "Empty", int InHealth = 1000, int InXp = 100); 를 호출해야 할 지 컴파일러 입장에서 모호하기 때문에 컴파일 에러 발생


	Player Kelvin("Kelvin"); //입력한 Kelvin과 default값인 1000, 100이 나오게 됨
	

	Player Jacob("Jacob", 100, 50); //입력한 Jacob, 100, 50이 나오게 됨

	return 0;
}

 

 

 

728x90
반응형

'C++' 카테고리의 다른 글

14. OOP Class & Object (1)  (77) 2024.02.22
13. Pointer And Reference (2)  (62) 2024.02.14
12. Pointer And Reference, Memory Allocate (1)  (107) 2024.01.30
11. Function (2)  (108) 2024.01.26
10. Function (1)  (127) 2024.01.25