36. 인스턴스 생성 순서와 생성자 내 가상 메서드 호출

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 주제: 인스턴스 생성 순서와 생성자 안에서의 가상 메서드 호출
//
// C# 에서 파생 객체를 생성할 때 필드 초기화자(field initializer)와 base/파생 생성자 본문은
// 정해진 순서로 실행된다. 특히 base 생성자가 가상 메서드를 호출하면, 아직 파생 생성자 본문이
// 실행되기 전임에도 파생 오버라이드가 디스패치된다. 이때 파생 필드가 어떤 상태로 보이는지가
// 핵심이다.
//
// 과제:
//  1) new Derived() 실행 시 아래 프로그램의 출력을 순서대로 예측하라.
//  2) 필드 초기화자(fromInitializer)와 생성자 본문 대입(fromCtorBody)이 Base 생성자에서
//     호출된 Init() 시점에 각각 어떤 값으로 보이는지, 그 이유(실행 순서)를 설명하라.
//  3) C++ 에서 같은 코드(base 생성자에서 가상 호출)의 동작과 무엇이 다른지 논하라.

using System;

class Base
{
    public Base()
    {
        Console.WriteLine("Base ctor start");
        Init();                                  // 가상 호출
        Console.WriteLine("Base ctor end");
    }
    protected virtual void Init() => Console.WriteLine("Base.Init");
}

class Derived : Base
{
    private int fromInitializer = 111;           // 필드 초기화자
    private int fromCtorBody;

    public Derived()
    {
        fromCtorBody = 222;                       // 생성자 본문 대입
        Console.WriteLine($"Derived ctor: initializer={fromInitializer}, ctorBody={fromCtorBody}");
    }

    protected override void Init()
        => Console.WriteLine($"Derived.Init: initializer={fromInitializer}, ctorBody={fromCtorBody}");
}

class Program
{
    static void Main() => _ = new Derived();
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.