이번 항목에선 객체를 초기화하는 방법들과 그 차이점에 대한 논의이다. 객체를 초기화 하는 방법으로는 크게 생성자 호출로 인한 초기화 방법과 복사 생성자 호출로 인한 초기화 두가지가 있다. 이 차이를 확실히 알아야지만, 최소한의 최적화(?)와 버그들을 잡을 수 있을 것이라고 나는 생각한다.

More Exceptional C++ 의 7단원, 37 항목에서 이 내용에 대해서 자세히 언급하고 있는데, 생각해 볼만한 질문을 두개 던저준다.


질문 1.

생성자 호출로 인한 초기화와 복사 생성자 호출로 인한 초기화의 차이점은 무엇인가?


질문 2.

다음 예제중 생성자 호출로 인한 초기화와 복사 생성자 호출로 인한 초기화를 구분 지어 설명 하라.



해설


질문 1. 각 차이는 무엇인가?

간단하게 설명한다면,

생성자 호출로 인한 초기화에는

1. 기본 생성자 호출로 인한 초기화
2. 인자를 전달하므로써 그 인자를 받는 생성자 호출로 인한 초기화
가 있고,


복사 생성자 호출로 인한 초기화

1. 같은 타입을 받아 들이는 복사 생성자로 인한 초기화
2. 묵시적으로 같은 타입으로 변환 시킨 후에, 복사 생서자를 호출하여 복사 되는 초기화가 있다.

이 모든것에 대해서 자유롭고 싶다면, 함수 호출식으로 생성자를 호출하여, 초기화 하는게 속편하다. 예) T t( u ); 이런식으로..

너무 간단하게 설명한 것 같아 일전에 정리해 두었던 것을 링크 시킨다.

참조 : http://ikpil.com/709 <-- 에서 42 항목 참조


질문 2. 구분 지어서 설명 할 수 있는가?

여기서 S 와 멤버 X에 대해서는 생성자 호출로 인한 초기화를 하는 것이다. 함수 호출식은 생성자 호출로 인한 초기화이라고 알아 두면 된다.


여기서는 책에서 언급 되지 않은 문제점이 있어 짚고 넘어가야 할 듯 싶다. 우선  이것은 복사 생성자 호출로 인해 t 를 초기화 하고 그것을 복사 생성자 호출로 인하여 반환 하는 것처럼 보인다. 반은 맞는 말이나 반은 틀린 말이기도 하다.

만약 T가 단일 인자값으로 그와 유사한 복사 생성자를 호출 할 수 있다면, 많은 변환을 거쳐서 t가 생성이 된다. 우선 만약 T가 int 형을 인자 1개를 받아 생성 될 수 있다면, 인자 1개가 T 형으로 변환된 후에, T의 복사 생성자가 호출 되어져 t가 초기화가 이루어 진다.

말로만 하면 잘 이해가 안가니, 예제코드(단일 인자값 복사 생성자의 문제점)를 첨부 한다.

이것은 "인자 1개만으로 생성자가 호출 될 수 있는 구조" 라면 .. 모두 가능하니, 꼭 짚고 넘어가야 한다.


다음~

s t 는 기본 생성자에 의한 초기화이고, r은 .. t객체의 Base 레퍼런스(.. 동적 참조라고 해야 하나.. )이다.


여기서 static_cast 를 제외하곤 전부 참조만 늘어 나는것이니 눈에 현혹되지 말지어니~ static_cast 의 경우, S의 복사 생성자 호출로 인하 t를 받아 들여서 splice 문제를 겪으며, S의 임시객체를 생성한다.

말이 어려울 수 있으나, 모든 경우를 설명하려면 이것 밖에 없다. 기본적으로 형변환은 "임시 객체를 만든다" 라고 알아 두기만 하면 그럭저럭(... 이면 사수와 진지한 커피 한잔을 마실... )넘어갈 수 있고, splice 는 S의 임시 객체 생성이므로 t의 T 부분이 잘려 나가는 문제점을 지적한다. 책에는 생략된것으로 보아, ... 기초이기 때문이지 않을까.. 한다.

마지막 중에 나머지는 한번 생각해 보는게 좋을것 같고, 재미있는 구문인

이 부분은 S의 생성자중 int형이나 그와 유사한 인자를 받는 생성자 호출로 인한 초기화가 이루어 진다.

즉, a[0] = 1, a[1] = 2, a[2] = 3 이때 이것이 컴파일러에 의해 생성자 호출로 인한 초기화가 될 수도 있고, 묵시적 형변환으로 후 복사 생성자에 의한 초기화가 될 수 있는 점을 알고 있어야 한다.

역시 자세한것은 질문 1의 참조를 봐야 할것이다.


총평

.. 아주 간단하면서 아주 할 말이 많은 변수 초기화에 대한 논의 였다. 페이지가 적어, 이 항목에 대해서 정리해야겠다 했다가, 더 많이 정리하게 된거 같다는 낭패란 느끼는 항목이다. 속편한것은 역시 함수 호출식 초기화가 제일 좋다 C++ 에서 = 에 의한 초기화는 이제 그만 종지부를 찍고 T t( 1 ); 로 초기화를 해야 하지 않을까 한다.


posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요