// 호출 전 lea ecx,dword ptr[객체]
// 멤버 함수 호출 후
mov dword ptr [this],ecx
_hp = 0;
mov eax,dword ptr [this]
mov dword ptr [eax],0
this->_hp = 1;
mov eax,dword ptr [this]
mov dword ptr [eax],1
Contructor Destructor
// [1] 기본 생성자 (인자가 없음)
Knight()
{
cout << "Knight() 기본 생성자 호출" << endl;
_hp = 100;
_attack = 10;
_posX = 0;
_posY = 0;
}
// [2] 복사 생성자 (자기 자신의 클래스 참조 타입을 인자로 받음)
// const가 빠져도 되지만, 그렇게 사용하는 경우는 잘 없다.
Knight(const Knight& knight)
{
_hp = knight._hp;
_attack = knight._attack;
_posX = knight._posX;
_posY = knight._posY;
}
// [3] 기타 생성자
Knight(int hp)
{
cout << "Knight(int) 생성자 호출" << endl;
_hp = hp;
_attack = 10;
_posX = 0;
_posY = 0;
}
// 소멸자
~Knight()
{
cout << "~Knight() 소멸자 호출" << endl;
}
Knight k1;
lea ecx,[k1]
call Knight::Knight (0691465h)
mov dword ptr [ebp-4],0
...
Knight k2(k1);
return 0;
mov dword ptr [ebp-0F0h],0
mov dword ptr [ebp-4],0FFFFFFFFh
lea ecx,[k1]
call Knight::~Knight (0691460h)
mov eax,dword ptr [ebp-0F0h]
}
암시적(implicit) 생성자
생성자를 명시적으로 만들지 않으면,
아무 인자도 받지 않는 [기본 생성자]가 컴파일러에 의해 자동으로 만들어짐.
Knight k3 = k1;
lea eax,[k1]
push eax
lea ecx,[k3]
call Knight::Knight (0AC1456h)
Knight k4;
lea ecx,[k4]
call Knight::Knight (0AC1451h)
k4 = k1;
mov eax,dword ptr [k1]
mov dword ptr [k4],eax
mov ecx,dword ptr [ebp-20h]
mov dword ptr [ebp-68h],ecx
mov edx,dword ptr [ebp-1Ch]
mov dword ptr [ebp-64h],edx
mov eax,dword ptr [ebp-18h]
mov dword ptr [ebp-60h],eax
return 0;
mov dword ptr [ebp-138h],0
lea ecx,[k4]
call Knight::~Knight (0391145h)
mov byte ptr [ebp-4],1
lea ecx,[k3]
call Knight::~Knight (0391145h)
mov byte ptr [ebp-4],0
lea ecx,[k2]
call Knight::~Knight (0391145h)
mov dword ptr [ebp-4],0FFFFFFFFh
lea ecx,[k1]
call Knight::~Knight (0391145h)
mov eax,dword ptr [ebp-138h]
}
// [3] 기타 생성자
// 이 중에서 인자를 1개만 받는 [기타 생성자]를
// [타입 변환 생성자]라고 부르기도 함
// 명시적인 용도로만 사용하고 싶은 경우 explicit 키워드를 붙임.
explicit Knight(int hp)
{
cout << "Knight(int) 생성자 호출" << endl;
_hp = hp;
_attack = 10;
_posX = 0;
_posY = 0;
}
void HelloKnight(Knight k)
{
cout << "Hello Knight" << endl;
}
// 암시적 형변환 -> 컴파일러가 알아서 바꿔치기
int num = 1;
float f = (float)num; // 명시적 < 우리가 코드로 num을 float 바구니에 넣으라고 주문하고 있음
double d = num; // 암시적 << 별말 안했는데 컴파일러가 알아서 처리하고 있음
Knight k5;
lea ecx,[k5]
call Knight::Knight (0CF11B3h)
mov byte ptr [ebp-4],4
k5 = 1; // explicit 키워드를 붙일 경우 컴파일 에러
push 1
HelloKnight(1); // explicit 키워드를 붙일 경우 컴파일 에러
k5 = (Knight)1; // explicit 키워드를 붙여도 명시적인 타입 변환은 가능
HelloKnight((Knight)5); // explicit 키워드를 붙여도 명시적인 타입 변환은 가능