본문 바로가기

예전/C, C++

[C++] 생성자 소멸자

생성자 소멸자


 

생성자( Constructors )란 클래스 객체를 생성할 때 자동적으로 호출되는 함수고, 소멸자( Destructors )란 클래스 객체가 소멸될 때 자동으로 호출되는 함수이다.


생성자 소멸자에서 중요한 개념은 호출 시점, 하는 일, 생성자의 종류 등 여러가지가 있다.



특징


생성자는 클래스와 동일한 이름이고, 반환 값이 없다. 소멸자도 마찬가지로 반환 값이 없고 함수이름 앞에 '~' 표시가 있다.



하는 일


생성자는 객체를 생성할 때 자동적으로 호출된다. 고로 객체 생성시 클래스에서 필요한 일들을 해주면 된다.

즉 객체가 제대로 동작할 수 있게 준비하는 일이다.


그 일에는 첫번째로 멤버 변수를 초기화 하는 일이 있다. cState라는 클래스를 만들어보자.




위의 예제는 클래스 생성자 소멸자의 전반적인 것을 말해주고 있다.

그 중에서 생성자 부분을 보면 헤더의 bool형 변수를 초기화 해주거나, 포인터 변수에 NULL값을 넣어준다.


 두번째로 생성자 내부에서 보듯 객체가 사용해야할 메모리를 준비하는 일도 한다. 포인터 형의 경우 동적으로 할당한 메모리를 사용할 때 생성자는 메모리를 할당하기에 아주 적당한 위치이다. 


이렇듯 클래스 시작전에 클래스에서 필요한 일을 생성자에서 해준다.



그렇다면 소멸자는 어떤 일을 할까?


소멸자는 클래스에서 동적으로 할당한 메모리를 해제해 주는 일을 한다. 

동적할당 포스트 에서 볼 수 있듯 메모리 해제는 아주 중요하다. 이러한 클래스의 정리를 해주는 것이 소멸자이다.



생성자의 종류


생성자 에는 꽤 여러 종류가 있다.


위에서 보았듯이 저런 형식을 가장 기본적인 생성자 즉 디폴트 생성자라고 한다.

디폴트 생성자는 인자가 없는 생성자라고도 불린다. 그렇다면 인자가 있는 생성자도 물론 있다.




인자가 있는 생성자는 호출동시에 초기화 해주는 생성자이다. 

다를 것은 없다. 단지 객체 생성 시 사용자가 원하는 값으로 초기화 할 수 있다는 것이다.


인자가 있는 생성자는 오버로드 규칙 내에서 여러 개 생성이 가능하다.



또 다른 생성자에는 복사 생성자가 있다.


복사 생성자란 다른 객체로부터 값을 복사해서 초기화 하는 것이다.




복사 생성자는 자신과 동일한 타입의 객체에 대한 레퍼런스를 인자로 받는 생성자이고, 초기화 할 때만 호출된다.


위의 한 줄은 별거 아닌 것같이 보이지만 복사생성자에 대한 대부분을 말해주고 있다.


복사생성자에는 또 다른 변수가 있다. 그것은 바로 얕은 복사깊은 복사이다.


얕은 복사와 깊은 복사는 문자열 포인터의 경우 발생한다.



string 이라는 함수에는 p라는 char형 포인터 변수가 있다. (char* p;)


얕은 복사의 경우 s.p가 가리키는 문자열의 주소 값만 p에 전달 하게 된다.

이는 만약 해당 위치의 문자열이 삭제되었을 경우에 문제를 일으킨다. 해당 위치에는 아무것도 없기 때문에 더이상 참조 혹은 가리킬 수 없게 된다.


따라서 문자열 전체를 복사해주는 깊은 복사가 필요한 것이다.




생성자가 반드시 있어야 하는 이유


생성자가 반드시 있어야 하는 이유는 반드시 생성과 동시에 초기화 해줘야 하는 변수들이 있기 때문이다.

클래스 헤더에선 생성과 동시에 초기화 해줘야 하는 변수들일지라도 초기화 할 수 없다.


그런 일을 생성자에서 해주는 것이다.


그러한 변수에는 const 속성을 가진 변수와 레퍼런스 변수가 있다.

만약 이러한 변수를 생성자에서 초기화 하지 않는다면 error가 발생해 더이상 진행 할 수 없게 된다.



const 속성을 가진 변수와 레퍼런스 변수는 반드시 위와 같은 형태로 초기화 해줘야 한다.

example은 작성자가 임의로 작성한 것이므로 신경쓰지 않아도 된다.





생성자와 소멸자에 대해서 알아보았다.


정리해 보면, 각각 하는 일이 명확함을 알 수 있다.

생성자는 클래스를 시작할 때 필요로 하는 일을 준비하고, 소멸자는 사용한 것중에 정리해야할 일을 정리한다.