특수한 멤버 함수
객체가 생성될 때 자동으로 호출됨
초기화 목적으로 유용하게 사용됨
클래스와 동일한 이름을 갖는 멤버 함수
반환형은 존재하지 않음
오버로딩 가능
class Player
{
public:
Player();//생성자
Player(std::string name);
Player(std::string name, int health, int xp);
private:
std::string name;
int health;
int xp;
};
생성자: 반환형이 없고 , 함수의 이름이 클래스의 이름과 동일.
인자가 없는 생성자
클래스의 생성자를 직접 구현하지 않으면 컴파일러가 기본적으로 만들어 줌
객체를 인자 없이 생성하면 호출된다.
객체를 생성 할 때 멤버 변수들의 값이 쓰레기 값이 들어가지 않게 초기화 시켜줄 수 있다
*주의*
class Player {
Player()// 객체가 생성될 때 어떤 필드 값을 가지고 생성될지 지정해주는 것
{
health = 100;
xp = 100;
name = "mkae";
}
};
#include <iostream>
class Player {
/*
Player()
{
컴파일 하면 자동으로 기본 생성자가 생김
}
*/
};
int main()
{
Player kim;
Player* enemy = new Player;
return 0;
}
#include <iostream>
class Account
{
public:
Account()//객체가 생성될 때 호출된다.
{
std::cout << "계좌 생성됨" << std::endl;
}
~Account()
{
std::cout << "소멸자 호출됨" << std::endl;
}
void Withdraw(double amount) //출금
{
if (balance - amount < 0)
return;
balance -= amount;
}
void Deposit(double amount) //입금
{
balance += amount;
}
private:
std::string name;
double balance; //계좌 잔액
};
int main()
{
//객체의 생성
Account kimAccount;
kimAccount.Withdraw(100);
return 0;
}
위의 결과를 보면 Account가 생성될 때, Account가 파괴될 때 호출이 되는 것을 직접 확인 할 수 있다.
오버로딩을 통해 객체가 생성 될 때 기본 값을 가지게 할지, 필드의 값을 지정해 줄 수 있다
매개변수에 따라 호출되는 생성자가 다르다.
각각의 생성자는 고유해야 함(매개변수가 달라야 함)
Account()
{
balance = 0.0;
name = "None";
}
Account(double val, std::string str)
{
balance = val;
name = str;
}
/*-----------중략--------- */
int main(){
Account Kim_account;//이때의 balance = 0.0, name = None 으로 생성
Account Lee_account = Account{100.0,"Lee"};
}
Account(double val, std::string str)
{
balance = val;
name = str;
}
/*-----------중략--------- */
int main(){
Account Kim_account;// ERR
Account* LeeAccount = new Account;//ERR
delete LeeAccount;
Account* ParkAccount = new Account {"park",1000.0}; // OK!
delete ParkAccount;
}
위와 같이 코드가 구현이 되어있다면 지정한 생성자 이외의 기본 생성자는 자동 생성되지 않는다!
Why?
생성자가 선언되고 필드의 값이 대입이 될 때까지 해당 필드의 값은 쓰레기 값이다.
이를 방지하기 위해서 사용한다.
Account(double val, std::string str)
{
balance = val;
name = str;
}
위와 같이 생성자를 작성했을 때 balance와 name의 값은 val과 str이 초기화 되기 전까지 여전히 쓰레기 값을 가지고 있다. 여기서는 문제가 크게 없지만 만약 아래와 같은 코드가 있다면
Account(double val, std::string str)
{
balance *= 2;
balance = val;
name = str;
}
위의 코드 balance의 값을 쓰레기 값의 2배를 해준다. 이와 같은 경우를 방지해 주는 것이다.
Account :: Account(double val, std::string str) // 전방선언 후 main뒤에서 함수 작성
: name{str}, balance {val}
{
}
Player::Player()
: name{"None"},health{100},xp{50}
{
}
즉, 위와 같이 작성해야 객체가 생성 되자마자 필드의 값이 초기화가 된다.
다양한 생성자의 오버로딩에 유사한 코드가 반복적으로 사용
오류의 가능성이 높아짐
생성자 위임을 통해 오류 가능성과 코드 반복을 줄일 수 있음
생성자 위임 사용 X
Account :: Account(double val, std::string str) // 전방선언 후 main뒤에서 함수 작성
: name{str}, balance {val}
{
}
Player::Player()
: name{"None"},health{100},xp{50}
{
}
생성자 위임 사용
Player::Player(std::string name_val,int health_val, int xp_val)
:name{name_val},health{health_val},xp{xp_val}
{
}
Player::Player()
: Player{"None",0,0}//Player 생성자 호출한 이후 인자를 넘겨주고있음
{
}
Player::Player(std::string name_val)
: Player{name_val,0,0}//Player 생성자 호출
{
}
#include <iostream>
class Player
{
public:
Player(std::string nameval = "None", int healthVal = 0, int xpVal = 0);//프로토타입
private:
std::string name;
int health;
int xp;
};
int main()
{
Player empty;
Player Kim("Kim");//kim,0,0
Player hero("Hero", 100, 0);
Player enemy("Enemy", 1000, 0);
return 0;
}
Player::Player(std::string nameVal, int healthVal, int xpVal)
:name{ nameVal }, health{ healthVal }, xp{ xpVal }
{
}
특수한 멤버 함수
객체가 소멸할 때 자동으로 호출됨
메모리 및 기타 리소스 ( 파일 close등)해제 목적으로 유용하게 사용됨
클래스와 동일한 이름 앞에 “~”를 갖는 멤버 함수
반환형 및 매개변수는 존재하지 않음
오버로딩 불가능
class Player
{
public:
Player();//생성자
Player(std::string name);
Player(std::string name, int health, int xp);
~Player(); //소멸자
private:
std::string name;
int health;
int xp;
};
객체 또는 객체의 포인터가 소멸되는 시점에서 자동으로 호출 된다
int main()
{
Player slayer;
Player Kim{ "kim",100,4 };
Player hero{ "Hero" };
Player enemy{ "Enemy" };
/*여기서 파괴자 호출 됨*/
return 0;
}
Player* enemy = new Player{"Enemy2",1000,0};
delet enemy;// 파괴자 호출 시점