생성자와 소멸자
생성자 : 여러개 존재 가능
소멸자 : 오직 1개만 존재 가능.
종류
이렇게 기본생성자랑 인자를 받는 생성자 만들어 주고
Knight hp(100);
이런식으로 인자를 넘겨줄 수 있다.
자기 자신의 클래스 참조 타입을 인자로 받음
k2라는 객체를 만들었는데 k1과 똑같이 만들고싶을 경우
Knight k2(k1);
일반적으로 '똑같은' 데이터를 지닌 객체가 생성되길 기대함.
이런식으로 구현을 해줄 수 있을 것이다.
우리가 구현해 놓지 않아도
이런식으로 자동으로 만들어 준다.
우리가 이전에는 생성자 안 만들어도 객체가 만들어 졌었는데
이유가 암시적 생성자 이다.
아무 인자도 받지 않는 "기본 생성자"가 컴파일러에 의해 자동으로 만들어짐.
그러나 Explicit(명시적)으로 아무런 생성자를 만든다면
자동으로 만들어지던 "기본생성자"는 더 이상 만들어 지지 않는다!
기본으로 만들어 진다.
Knight k1;
Knight k2 (k1);
Knight k3 = k1;
이렇게 만들어 줄 수 있는데
Knight k3 = k1; // 이거는 그냥 생성 함과 동시에 복사를 하는
// 복사 생성자 동작 방식이다.
이거랑
Knight k4;
k4 = k1;
이거랑은 완전히 다르다.
Knight k4;
k4 = k1;
이부분은 지금 "얕은 복사"를 통해서 스택에 있는k4라는 객체의 변수가
k1과 같은 주소를 가르키는 상태이다.
기타 생성자 중에서도 인자를 1개만 받는 "기타 생성자"를
"타입 변환 생성자" 라고 부르기도 한다.
이런애들.
그러면 말 그대로 "타입 변환"할 때 사용되는 아이인가?
=> 맞다.
타입 변환이라 함은 바구니가 변한다는 것.
(값 부분 (데이터) 변환?)
int num = 1;
float f = num;
암시적으로 형변환이 되어서 컴파일 에러가 안남.
int num = 1;
float f = (float)num;
이게 명시적 형변환.
우리가 코드로 직접 변경.
좋고도 하고 나쁘기도 한게 굳이 말하지 않아도 알아서 변환을 해준다.
혼동과 버그를 주기도한다.
Knight k1;
k1 = 2;
이런게 말이 되나? 이상하다. 그런데
지금 인자를 하나를 받은 이 "타입 변환 생성자" 때문에
k1 = 2; 이런게 가능하다.
객체 변수명에 정수 2를 넣음...
이런 생성자 버젼 (타입 변환 생성자)가 있으면
정수를 가지고 Knight를 초기화 할 수 있는 것과 더불어,
이런식의 형변환이 자동으로도 일어난다.
즉, k1 = 2;하면 타입 변환 생성자 호출 된다.
void HelloKnight(Knight k)
{
}
int main()
{
Kngiht k5;
HelloKnight(k5); // 일반적인 경우 이렇게 넣어주는게 당연함.
// 그런데
HelloKnight(5); // 이렇게만 넣어주어도 생성자가 호출이된다.
// 이게 컴파일러가 암시적으로
// 타입을 변환해서 넣어주는게 "문제"가 될 수 있다.
}
즉 HelloKnight에 5를 넣어주게 되면
Knight가 만들어 지면서
"타입 변환 생성자"를 통해서 이런버젼이 하나가 만들어 지는 것이다.
그래서 컴파일러가 암시적으로 변환 시키는게 싫다.
"명시적"으로 하고싶다고하면은
explicit Knight(int hp)
{
}
// 생성자 앞에 "explicit" 키워드를 붙여주어야한다.
타입 변환 용도로 암시적으로 사용하지 않을 것이다.
그러면 이제 명시적으로 사용을 할려면
앞에 (Knight)로 타입 변환 생성자를 이렇게 호출 해야한다.