전체 코드

✅ 1. 생성자와 소멸자란?

💡 객체의 생성과 소멸

함수설명
생성자(Constructor)객체가 생성될 때 호출되는 특수한 함수
소멸자(Destructor)객체가 소멸될 때 호출되는 특수한 함수
  • 생성자는 여러 개 존재 가능 (오버로딩 가능)
  • 소멸자는 클래스당 하나만 존재 (오버로딩 불가능)
  • 객체의 수명 동안 자동으로 호출되며, 명시적으로 호출할 필요 없음

📌 2. 생성자 코드 예제 (Knight 클래스 설계)

✅ 2.1 헤더 포함 및 네임스페이스 설정

#include <iostream>  // 입출력 기능 제공
using namespace std; // std:: 생략
  • #include <iostream> : cout, cin을 사용하기 위해 포함
  • using namespace std; : std::cout 대신 cout으로 사용 가능

✅ 2.2 Knight 클래스 선언

class Knight
{
public:
    // [1] 기본 생성자 (인자가 없음)
    Knight()
    {
        cout << "Knight() 기본 생성자 호출" << endl;
        _hp = 100;
        _attack = 10;
        _posX = 0;
        _posY = 0;
    }

📌 기본 생성자

  • 객체가 생성될 때 자동으로 호출됨
  • hp, attack, posX, posY를 초기화
  • 출력: "Knight() 기본 생성자 호출"

✅ 2.3 복사 생성자

    // [2] 복사 생성자 : 자기 자신의 클래스 참조 타입을 인자로 받음
    // 같은 데이터를 가진 객체가 생성되길 기대함
    Knight(const Knight& knight)
    {
        cout << "Knight(const Knight&) 복사 생성자 호출" << endl;
        _hp = knight._hp;
        _attack = knight._attack;
        _posX = knight._posX;
        _posY = knight._posY;
    }

📌 복사 생성자

  • 객체를 복사할 때 호출됨
  • 같은 데이터를 가진 새로운 객체를 생성
  • 출력: "Knight(const Knight&) 복사 생성자 호출"

📌 사용 예시

Knight k2(k1);   // k1을 복사하여 k2 생성 (복사 생성자 호출)
Knight k3 = k1;  // k1을 복사하여 k3 생성 (복사 생성자 호출)

✅ 2.4 기타 생성자 (오버로딩)

    // [3] 기타 생성자 (인자를 받는 생성자)
    explicit Knight(int hp)
    {
        cout << "Knight(int) 생성자 호출" << endl;
        _hp = hp;
        _attack = 10;
        _posX = 0;
        _posY = 0;
    }

📌 기타 생성자 (타입 변환 생성자)

  • 1개의 인자만 받는 생성자 → "타입 변환 생성자"
  • explicit을 사용하면 암시적 형변환 방지
  • 출력: "Knight(int) 생성자 호출"

📌 암시적 형변환 방지

Knight k5 = 1;   // ⚠️ 암시적 변환 허용되지 않음 (explicit 때문)
Knight k5 = (Knight)1;  // ✅ 명시적 변환 필요

✅ 2.5 여러 개의 인자를 받는 생성자

    Knight(int hp, int attack, int posX, int posY)
    {
        _hp = hp;
        _attack = attack;
        _posX = posX;
        _posY = posY;
    }

📌 다양한 초기화 방식 지원

  • 다양한 값으로 객체를 초기화할 수 있도록 여러 생성자 오버로딩
  • 사용 예시
Knight k1(100, 10, 0, 0);  // 4개의 값으로 초기화

✅ 2.6 소멸자

    // [4] 소멸자
    ~Knight()
    {
        cout << "Knight() 소멸자 호출" << endl;
    }

📌 소멸자

  • 객체가 소멸될 때 자동으로 호출
  • 메모리 해제 등의 처리를 수행 가능
  • 출력: "Knight() 소멸자 호출"

📌 소멸자 호출 시점

{
    Knight k1;
} // ⚠️ k1이 스코프를 벗어나면서 소멸자 호출됨

✅ 2.7 멤버 함수

    void Move(int y, int x);
    void Attack();
    void Die()
    {
        _hp = 0;
        cout << "Die" << endl;
    }
  • Move() : posX, posY 변경
  • Attack() : 공격 수행
  • Die() : hp를 0으로 설정 후 "Die" 출력

📌 3. main() 함수 - 객체 생성 및 사용

int main()
{
    // 기본 생성자 호출
    Knight k1;

    // 복사 생성자 호출
    Knight k2(k1);
    Knight k3 = k1;

    // 복사 연산자 (대입 연산)
    Knight k4;
    k4 = k1;

    k1.Move(2, 2);
    k1.Attack();
    k1.Die();

    // 암시적 형변환 (explicit 사용 시 에러 발생)
    Knight k5;
    k5 = (Knight)1;  // 명시적 형변환만 가능

    return 0;
}

📌 출력 예시

Knight() 기본 생성자 호출
Knight(const Knight&) 복사 생성자 호출
Knight(const Knight&) 복사 생성자 호출
Knight() 기본 생성자 호출
Move
Attack
Die
Knight() 소멸자 호출
Knight() 소멸자 호출
Knight() 소멸자 호출
Knight() 소멸자 호출
Knight() 소멸자 호출

📌 4. explicit 키워드와 타입 변환

explicit Knight(int hp)

📌 암시적 형변환 방지

Knight k5 = 1;  // ❌ 암시적 형변환 → 오류 발생
Knight k5 = (Knight)1;  // ✅ 명시적 형변환 필요

📌 암시적 형변환 예제

float f = num;   // 암시적 형변환
float f = (float)num;  // 명시적 형변환

📌 5. this 포인터

void Die()
{
    _hp = 0;
    this->_hp = 1;  // this는 자기 자신을 가리킨다
    cout << "Die" << endl;
}

📌 this 포인터

  • 멤버 함수 내부에서 객체 자기 자신을 가리킴
  • 멤버 변수와 지역 변수를 구분할 때 사용 가능

profile
李家네_공부방

0개의 댓글