[C++]멤버이니셜라이져(멤버초기화리스트)

멤버 초기화 리스트(Mmber Initialization List)라고한다.

생성자의 역할인 멤버변수의 초기화를 대신할 수 있다.

보통 멤버 이니셜라이져라고 부르는데 꼭 사용해야 하는 경우는 4가지가 있다.


1. 상수 멤버의 초기화 (C++11의 경우는 상수멤버변수 선언과 동시에 그냥 초기할 수 있음.)

2. 레퍼런스 멤버 초기화

3. 객체멤버의 초기화

4. 부모클래스의 멤버변수초기화

1, 2, 3번은 비슷한 맥락에서 이해될 수 있다. 4번의 경우는 상속과 객체생성 메커니즘에 대해 잘 이해해야 이해할 수 있다.


2015/04/29 - [프로그래밍/c++] - 부모클래스의 멤버변수 초기화


멤버이니셜라이져 문법

아래는 일반적인 멤버 초기화 방법이다.



 아래는 멤버 이니셜라이저 문법을 사용하였다.


두 경우 결과는 같다.

이 경우 굳이 {}를 비워두고 멤버 이니셜라이져 문법을 사용하지 않아도 된다. 이 문법을 꼭 사용해야 하는 이유는 따로 있다.

멤버 이니셜라이져를 통한 초기화는 객체의 생성 이전에 이루어진다. 이 점을 이해하면 처음에 말한 1, 2, 3번 경우 왜 이 문법을 사용 해야 하는지 감이 올 것이다.


생성자 선언 다음에

:을 쓴 후 멤버 초기화 리스트를 적는다.


x(_x) 는 x에 _x를 대입하라는 뜻이다.


다음 특성은 해답에 대한 단서가 된다.

1. 상수는 선언과 동시에 초기화 되어야 한다.C++11이전 문법은 멤버변수의 초기화가 불가능했다. 클래스 정의는 실제 메모리에 인스턴스를 생성하는 작업이 아니기 때문이다. 단 static으로 선언한 멤버변수는 초기화가 가능하다.


2. 레퍼런스 변수 또한 생성과 동시에 초기화 되어야 한다. 1번과 마찬가지로 객체 생성 시점에 초기화가 되어야 한다.


3. 클래스가 객체 포인터가 아닌 객체멤버변수를 가지고 있다면, 클래스의 객체가 생성된 후엔 객체멤버에 대한 생성자를 호출할 수 없게 된다.


3가지 겨우 객체 생성 시점에 초기화를 해야 하지만 클래스의 객체가 생성된 후에는 이미 멤버변수들이 선언된 상태기 때문에 초기화가 안되게 된다.

객체 생성 전과 후에 모두 초기화가 안되므로 멤버 초기화 리스트라는 특수한 방법을 이용한다.

객체가 생성되기 직전 멤버변수를 선언과 동시에 초기화 한 후 객체를 생성하면 문제가 없을 것이다.

상수 변수, 레퍼런스 변수, 객체 변수 전부 생성과 동시에 초기화를 위해 멤버 초기화 리스트를 사용한다. 


소스코드를 보며 이해해보자.

1. 상수 멤버의 초기화

-std=c++11 컴파일옵션으로 해결할수있다.-std=c++11 컴파일옵션으로 해결할수있다.




2. 레퍼런스 초기화


3.멤버객체변수의 초기화

4번의 경우는 해야 할 이야기가 많으므로 따로 포스팅을 하겠습니다.


상속과 관련한 내용에 대한 이해가 필요합니다.


이 댓글을 비밀 댓글로
    • 3번
    • 2017.09.15 23:31
    덕분에 왜 쓰는지 이유를 잘 알게 되었습니다! 감사합니다.
    그런데 3번의 경우에는 아직도 왜 멤버 이니셜라이져를 사용하는지 이해가 가지 않습니다. 더 자세한 설명 부탁드릴 수 있을까요?
    객체 멤버를 초기화하려면 이니셜라이져를 사용하지 않고 그냥 생생자로 초기화시켜주면 되지 않나요?
    • 안녕하세요. 오래전 글이라서 기초적인 내용인데 가물가물 하네요.^^
      좀 복잡해도 잘 읽어보세요.~
      우선 A라는 클래스가 있고 그 안에 멤버 객체 obj가 선언되어 있다고 합시다. A 클래스의 객체를 생성할 때 생성자를 호출하겠죠? 생성자를 호출하기 전에는 아직 obj가 초기화 된 상태가 아닙니다. 그런데 A클래스의 생성자가 호출될 때 obj객체를 초기화 해 주지 않으면 디폴트 생성자가 호출됩니다. 이건 원하는 것이 아닐 수 있습니다.(디폴트가 아닌 다른 생성자를 사용하고 싶다면?) 만약 디폴트 생성자로 초기화 되었다면 다시 생성자를 호출할 수 없기 때문이죠. 따라서 obj 객체의 초기화 시점(A클래스의 생성자의 호출 시점)에서 멤버 이니셜라이져로 obj 객체의 적절할 생성자를 호출하는 겁니다. 맞나요? 너무 오래되어서 한번 다시 확인해 봐야 겠지만 이 내용이 맞는것 같네요.