생성자와 소멸자

namu·2022년 7월 19일
// 호출 전 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개만)
// [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 키워드를 붙여도 명시적인 타입 변환은 가능
profile
안녕하세요

0개의 댓글