생성자, 소멸자

윤이령·2026년 4월 20일

생성자

  • 객체가 생성된 직후에 자동으로 호출되는 함수
클래스_이름()

호출 순서

  • 부모 -> 자식
#include <iostream>
using namespace std;

class character {
public:
    character() {
        cout << "character 클래스 생성자" << endl;
    }
};

class monster {
public:
    monster() {
        cout << "monster 클래스 생성자" << endl;
    }
};

class monster_a : public monster, character {
public:
    monster_a() {
        cout << "monster_a 클래스 생성자" << endl;
    }
};

int main() {
    monster_a forestMonster;
    return 0;
}

/* 결과
monster -> character -> monster_a
*/

기본 생성자

class monster{
public:
	//기본 생성자
	monster(){...};
};

class monster_a : public monster{
public:
	//자식 클래스 기본 생성자
	monster_a() {...};
    //매개변수가 추가된 생성자
    monster_a(int x, int y) {...};
    //변수 초기화가 추가된 생성자
    monster_a(int z_order) : z_order(z_order) {...};
    //명시적으로 정의한 복사 생성자
    monster_a(monster_a & copy_monster) {...};
};

생성자에서 다른 생성자 호출

//...생략...
class monster_a : public monster, character {
public:
	//초기화 목록으로 다른 생성자 호출
    monster_a() : monster_a(10, 10) {
        cout << "monster_a 클래스 생성자" << endl;
    }

	//초기화
    monster_a(int x, int y) : location(x, y) {
        cout << "monster_a 클래스 생성자(매개변수 추가)" << endl;
    }

    void show_location() {
        cout << "위치(" << location[0] << ", " << location[1] << ")" << endl;
    }
private:
    int location[2];
};

int main(){
	monster_a wood_monster;
    wood_monster.show_location(); // (10, 10)
    return 0;
}

복사 생성자

  • 객체가 복사될때 자동으로 호출되는 생성자

얕은 복사

  • 기본 복사 생성자
  • 포인터 변수가 있을 경우 주소값만 복사됨
  • 주소값이 같으므로 같은 메모리를 공유함 -> 값 변경 또는 delete위험성 있음

깊은 복사

  • 포인터 변수가 있을 경우 레퍼런스로 원본 값을 가져와서 새 메모리, 값 복사를 해줌
  • 한 객체를 수정해도 서로 영향 없음
class monster {
public:
    int* hp;

    monster(int v) {
        hp = new int(v);
    }

	// 레퍼런스로 복사 대상을 가져옴
    monster(const monster& other) {
    	//새로운 메모리를 잡고, 값 복사
        hp = new int(*other.hp);
    }
};
class monster_b : public monster, character {
public:
	//참조로 player객체를 받아옴
	monster_b(player& attack_target) : monster_type("일반"), location{ 0, 0 }, unique_id(++total_count), target(attack_target) {
		difficult_level = 10;
		quiz = new char[1024];
	};
	~monster_b() {
		delete[]quiz;
		total_count--;
	}

	monster_b(const monster_b& ref);

	void set_quiz(const char* new_quiz) { strcpy_s(quiz, 1024, new_quiz); };
	void set_type(string type) { monster_type = type; }
	void set_difficult_level(int level) { difficult_level = level; }
	void set_location(int x, int y) { location[0] = x; location[1] = y; }
	char* get_quiz() { return quiz; }
	string get_type() { return monster_type; }
	int get_difficult_level() { return difficult_level; }
	int get_x_location() { return location[0]; }
	int get_y_location() { return location[1]; }

private:
	string monster_type;
	int location[2];
	static int total_count;
	const int unique_id;
	player& target;
	int difficult_level;
	char* quiz;
};

int monster_b::total_count = 0;

// target은 ref가 참조하고 있는 동일한 player 객체를 그대로 참조한다
// (player 객체 자체를 복사하는 것이 아니라 참조만 공유함)
monster_b::monster_b(const monster_b& ref) : unique_id(++total_count), target(ref.target) {
	quiz = new char[1024];
    // quiz는 포인터이므로 서로 다른 메모리를 할당하고 내용을 복사해야 한다 (deep copy)
	strcpy_s(quiz, strlen(ref.quiz) + 1, ref.quiz);
	monster_type = ref.monster_type;
	difficult_level = ref.difficult_level;
	location[0] = ref.location[0];
	location[1] = ref.location[1];
}

소멸자

  • 객체가 소멸할 때 필요한 메모리 해제나 외부 환경을 객체 생성이전 상태로 변경하는 등의 일을 함
~클래스_이름()
//소멸자로 동적할당 해제
~monster_b() {
	delete[]quiz;
	total_count--;
}
  • virtual 키워드 안쓰면 자식 클래스 소멸자 호출 x
#include <iostream>

using namespace std;

class monster {
public:
	monster() {
		cout << "monster클래스 생성자" << endl;
	}
	~monster() {
		cout << "monster클래스 소멸자" << endl;
	}
};
class monster_a : public monster {
public:
	monster_a() {
		cout << "monster_a 클래스 생성자" << endl;
	}
	~monster_a() {
		cout << "monster_a 클래스 소멸자" << endl;
	}
};

int main() {
	monster* forest_monster = new monster_a();
	delete forest_monster;
	return 0;
}

  • virtual키워드로 가상소멸자로 만들면 부모 객체가 소멸할 때 자식 객체도 소멸
#include <iostream>

using namespace std;

class monster {
public:
	monster() {
		cout << "monster클래스 생성자" << endl;
	}
	virtual ~monster() {
		cout << "monster클래스 소멸자" << endl;
	}
};
class monster_a : public monster {
public:
	monster_a() {
		cout << "monster_a 클래스 생성자" << endl;
	}
	virtual ~monster_a() {
		cout << "monster_a 클래스 소멸자" << endl;
	}
};

int main() {
	monster* forest_monster = new monster_a();
	delete forest_monster;
	return 0;
}

0개의 댓글