KoreanFoodie's Study

C++ 기초 개념 4-3 : 복사 생성자와 소멸자 본문

Tutorials/C++ : Beginner

C++ 기초 개념 4-3 : 복사 생성자와 소멸자

GoldGiver 2021. 12. 20. 18:49

모두의 코드를 참고하여 핵심 내용을 간추리고 있습니다. 자세한 내용은 모두의 코드의 씹어먹는 C++ 강좌를 참고해 주세요!

소멸자

클래스 생성자에서 만들어 준 자원은 객체가 소멸할 때 반드시 해제되어야 메모리 누수(memory leak)이 일어나지 않는다.

#include <string.h>

class Marine {
 char* name;
 
 public:
     Marine();
     Marine(const char* marine_name);
     ~Marine();
};

Marine::Marine() {
    name = NULL;
}

Marine::Marine(const char* marine_name) {
    name = new char[strlen(marine_name) + 1];
    strcpy(name, marine_name);
}

Marine::~Marine() {
    if (name != NULL) {
    	delete[] name;
    }
}

위의 Marine 클래스에서는, ~Marine()에서 name을 해제하고 있음을 알 수 있다.

 

소멸자는 객체가 포함된 scope가 닫힐 때 자동으로 호출된다. 아래 예시를 보자.

class Test {
    char c;
    Test(char ch) : c(ch) {}
	~Test() {};
}

simple_function() {
    Test b('b');
}

int main() {
    Test a('a');
    simple_function();
}

이 경우, a의 생성자 호출 -> b의 생성자 호출 -> b의 소멸자 호출 -> a의 소멸자 호출 순으로 함수들이 호출된다.

 

복사 생성자 (Copy Constructor)

 

기본 복사 생성자

컴파일러는 기본적으로 복사 생성자를 자동으로 생성해 준다. 하지만 자동 생성된 복사 생성자는 얕은 복사(shallow copy)밖에 하지 못하므로, 다음과 같은 문제가 생긴다.

Marine::Marine(const Marine& m) {
    this.name = m.name; // shallow copy
}

만약 name이 같은 주소를 가리키도록 만들면, 한 객체에서 소멸자가 호출되어 name의 메모리 공간이 해제된 후, 다른 객체에서 소멸자가 호출된다. 해제된 메모리 공간을 다시 해제하려는 시도는 런타임 오류를 발생시킨다.

따라서, 복사 생성자를 호출할 때는, 동적 할당이 되는 변수가 있을 경우 깊은 복사(deep copy)를 해야 한다.

 

커스텀 복사 생성자

Marine::Marine(const Marine& m) {
    char* name = new char[strlen(m.name) + 1];
    strcpy(name, m.name);
}

 깊은 복사(deep copy)를 사용하여 "진짜" 복사 생성자를 만들자.

 

Comments