컴퓨터공학/C++

[C++] 초기화 리스트

Pyxis 2024. 8. 22. 10:26

 

[ C++ : 초기화 리스트 ]

 

멤버 변수를 초기화하는 다양한 문법

 

초기화는 왜 해야할까 ?

 

클래스에서 멤버변수를 초기화 해주지 않는다면 쓰레기 값이 들어있음.

visual studio C++ x86 Debug를 기준으로 보자.

class Knight내에서 int hp가 있고, 기본 생성자로만 생성한다면

hp에는 0xcccccccc라는 값이 들어있다.

→ 이 값은 초기화 되지 않은 쓰레기 값

 

방금 만든 Knight의 hp가 의도치 않게 쓰레기값인 음수로 설정되어

곧 바로 죽을 수 있다.

처음에 설계를 할 때는 들어가자마자 정리정돈을 하고 시작해야지 예측할 수 없는 문제를 예방할 수 있다.

 

[ 초기화 방법 ]

- 생성자내에서

- 초기화리스트

- C++11 문법 (선언과 동시에 초기화)

 

[ 초기화 리스트 ]

- 상속 관계에서 원하는 부모 생성자를 호출할 때 필요하다.

- 생성자내에서 초기화 vs 초기화 리스트

-- 일반 변수는 별 차이 없음

-- 멤버 타입이 "클래스"인 경우 차이난다.

-- 정의함과 동시에 초기화가 필요한 경우 (ex 참조 타입, const 타입)

 

[ 여기서 잠깐 ]

클래스 설계를 할 때, 예를 들어 Inventory 클래스를 생각해보자

Knight가 Inventory를 가진다고 할 때, 다음 관계를 생각해 봐야 함

 

[ Is-A (Knight Is-A Player?) OK → 상속관계 ]

[ Has-A (Knight Has-A Inventory?) OK → 포함관계 ]

 

상속관계라면 "상속", 포함관계라면 "멤버 변수"가 된다.

그럼 Inventory 클래스를 멤버 변수로 갖게 되는데,

Knight의 생성자 선처리 영역에서 Inventory의 생성자도 호출된다.

Inventory 클래스의 생명 주기는 Knight를 따라서 생성되고 소멸된다.

 

갑자기 이 이야기는 왜 하는걸까?

 

생성자의 선처리 영역에서 부모의 다른 버전 생성자를 지정할 수 있었던 것 처럼

포함 관계가 있을 때도 Inventory를 내부에서 새로 만들어주는게 아니라 한 방에 처리할 수 있게 유도 해야 함.

→ 기존 생성자내에서 하나를 새로 생성하면, 선처리 영역에서 미리 Inventory를 생성하기 때문에 덮어써서 한번 더 생성하게 되고, 덮어쓴 후 기존에 생성된 부분은 필요없다고 느낄테니 "생성한 뒤에" 기존에 기본 생성자로 생성된 Inventory의 소멸자도 호출된다.

Knight() : Player(1), _hp(100), Inventory(50)

{

        //

}

 

[ 결국 결론은 ? ]

초기화를 할 때는 일반적인 함수처럼 내부에서 하기보다는, "초기화 리스트"를 이용하는게 훨씬 더 좋다.

성능적인 이슈도 있지만 사실은 이렇게 할수밖에 없는 경우도 종종 생기게 되는데, 위에서 살펴 본 초기화 방법들 중 세 번째 경우인 "참조 타입, Const 타입"의 경우가 해당된다.

 

 

'컴퓨터공학 > C++' 카테고리의 다른 글

[Modern C++] std::forward  (0) 2024.09.14
[Modern C++] Lambda  (0) 2024.09.11
[C++] 동적할당  (0) 2024.08.23
[C++] 상속성  (0) 2024.08.21
[C++] 생성자와 소멸자  (0) 2024.08.20