이 항목에선 Jan Chrisiaan van Winkel 이라는 학생이 제공한 예제에서 어떤 실수가 있는지 살펴본다.


1 ) 다음 소스를 보고, 어디가 문제인지 지적해보라.

난 이 문제를 보고, 재석이와 함께 고민했었다. 어느 부분이 문제일거 같다는 느낌(?)이 들었지만, 정확하게 지적하지 못했기 때문에, 나는 틀린것이나 다름이 없다.그런던 중, 동우에게, 소스 코드를 보여주고, 어디가 문제 일지 물어 보았을 때, 잠시 생각하더니, 정확하게 지적을 했다.

그 지적은, 21 라인에서, 초기화 순서가 A() 가 먼저인데, 생성되지 않은 string s 의 객체에 대입하니 문제가 생긴것 이라고 정확하게 지적했다.

난 이 지적이 정확하게 맞다고 인정했고, 좀 더 곰곰히 생각해 보았다. 이 생각은, "생성되지 않은 객체의 operator= 의 호출이 왜 정상적으로 호출 되어 질까?" 에 두었다.

이것으로 한가지 추측이 하게 된다. "인스턴스화된 함수는 정상적이나, 함수가 사용 하는 스택이 문제이기에, 호출만은 정상적으로 호출 가능할 것이다" 이다.

위의 추측을 추측1 이라고 이라고 우선 정하고, 우선 진행하자.

다른 문제로 , 21 라인에서, A의 객체가 생성되기도 전에 A::f() 의 함수가 호출 되어 짐으로 문제가 될 수 있다. 현재 A::f() 에선 A의 멤버 변수를 사용하여, 작동 되는 함수가 아니기에, 정상 호출이 될 수 있었다.

위에서 정한 추측1은, 이 문제가 정상적으로 됨으로, 증명 된다는 것을 알 수 있을 것이다.


자~ 문제 1은 넘어가고~


2 ) 어떠한 C++ 클래스 형식의 객체를 생성할 때, 그 객체의 여러 부분들이 어떤 순서로 초기화 되는가? 최대한 구체적이고 완전하게 설명하라. 다음 예제에 나온 X 객체의 여러 부분들이 초기화되는 순서를 말하라.

이 초기화 순서를 알기 전에, 상속에 따른 클래스가 어떻게 초기화 되는 규칙을 먼저 알아야 할 것 같다.

첫째, 상속 계층 중, 가장 하위의 파생 클래스(여기선 D1, D2)의 생성자가 가상 기반 클래스의 생성자를 제일 먼저 호출 하되, 다중 상속의 왼쪽 부터 호출 하게 된다.

둘째, 그 뒤, 일반적인 상속 정의 순(왼쪽부터)과 객체 초기화 순(위쪽부터)으로 초기화 되어 진다.

이것을 순으로 정리하면

X의 가장 하위 파생 클래스 D1, D2의 생성자가 가상 기반 클래스 V1, V2 의 생성자 호출을 최상위로 올리고,

B1 호출, V1 호출  하고

B1 호출, B2 호출, V2 호출 하고,

비가상 기반의 상속순인,

D1 호출 하고

B3 호출, D2 호출 한 뒤에

X의 멤버 M1 호출, M2 호출 하고,

X의 생성자를 끝 맞친다.


증거 코드를 첨부 한다.


총평

재미있는 항목이였고, 스택이 꼬여도, 함수 호출만은 정상적으로 이루어 질수 있음을 알게 되었다. 간단하면서도, 참으로 복잡할 수 있도 있다는 것을 알려 주는 항목이기도 하다. .. 불필요한 상속을 자연스럽게 꺼리게 하는 항목이기도 하다. 왜냐하면, 상속 계층 구조 상, 상속 된 객체의 상태를 생각하기 매우 힘들어 지기 때문이라고 생각 한다.


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

댓글을 달아 주세요

  1. 최익필안티 2009.01.14 02:25 신고  Addr  Edit/Del  Reply

    배신자