Effective C++ (개인 공부)

객체 초기화

TIN9 2022. 11. 4.
반응형

객체 초기화 순서

  1. 기본 클래스는 파생 클래스보다 먼저 초기화된다.
  2. 클래스 데이터 멤버는 그들이 선언된 순서대로 초기화된다.

1번 항목 예시

 

'기본 클래스 Widget이 있고 파생클래스 Child가 있다고 가정'

 

위의 사진과 같이 기본 클래스를 먼저 초기화 이후 파생클래스가 초기화 된다.


2번 항목 예시

h 구성

Widget.h

class CWidget
{
public:
	CWidget();
	~CWidget();

private:
	int Test1;
	int Test2;
	int Test3;
	int Test4;
	int Test5;
}

cpp 구성

widget.cpp

#include "Widget.h"

CWidget::CWidget()	:
	Test1(5),
	Test5(5),
	Test2(5),
	Test4(5),
	Test3(5)
{
}

CWidget::~CWidget()
{
}

위의 코드처럼 초기화를 Test1->Test5->Test2->Test4->Test3 순서로 구성한다고 해도 실질적으로 초기화 되는 순서는

h파일에 선언된 순서에 따라 초기화가 진행된다(디버깅을 통해 확인 가능)


1번

2번

3번

4번

위의 사진을 보면 헤더에 선언한 순서대로 Test1 -> Test2 -> Test3 -> Test4 -> Test5의 순서로

초기화가 진행되는것을 볼 수 있다.


멤버 초기화 리스트에 넣는 멤버들의 순서는 클래스에 선언한 순서와 동일하게 맞춰주는게 좋다.
그래야 초기화를 했는지 안했는지 바로 판단이 가능하고 협업할때 혼동을 막을 수 있다고 함.

 

 


비지역 정적 객체 초기화

비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다.

자세한 내용은 Effective C++ 78p 참고

 

정적 객체

정적 객체란 자신이 생성된 시점부터 프로그램이 끝날 때까지 살아 있는 객체를 일컫는다.

main()함수 실행이 끝날때 정적 객체의 소멸자가 호출됨

 

정적 객체의 범주

  1. 전역 객체
  2. 네임스페이스 유효범위에서 정의된 객체
  3. 클래스 안에서 static으로 선언된 객체
  4. 함수 안에서 static으로 선언된 객체
  5. 파일 유효범위에서 static으로 정의된 객체

위의 내용 중 함수 안에 있는 정적 객체는 지역 정적 객체이고

나머지는 비지역 정적 객체이다.

번역 단위

번역단위란 컴파일을 통해 하나의 목적 파일(Object File)을 만드는 바탕이 되는 소스 코드를 일컫는다.

여기서 번역은 소스의 언어를 기계어로 옮긴다는 의미

기본적으로 소스 파일 하나가 되는데, 그 파일이 #include하는 파일까지 합쳐서 하나의 번역 단위가 된다.


요약

 

  • 기본제공 타입의 객체는 직접 손으로 초기화 한다. 경우에 따라 저절로 되기도 하고 안 되기도 하기 때문
  • 생성자에서는, 데이터 멤버에 대한 대입문을 생성자 본문 내부에 넣는 방법으로 멤버를 초기화하지 말고 멤버 초기화 리스트를 즐겨 사용하자. 그리고 초기화 리스트에 데이터 멤버를 나열할 때는 클래스 각 데이터 멤버가 선언된 순서와 똑같이 나열하자.
  • 여러 번역 단위에 있는 비지역 정적 객체들의 초기화 순서 문제는 피해서 설계해야 함. 비지역 정적 객체를 지역 정적 객체로 바꾸면 된다.
반응형

댓글