부트캠프

팀 콘솔 RPG3

noyyo 2023. 8. 30. 22:32

오늘은 코드를 짜는 도중에 생성자와 관련되어서 한 번 에러가 났다.

A라는 클래스의 생성자에서 B 클래스를 만들고, B클래스는 A클래스를 참조하는 경우였다.

이런 구조로 코드가 짜여있어서 생성자가 끝나지 않고 계속해서 순환해서 돌다가 스택이 넘쳐버리는 사태가 발생했다.

 

해당 구조를 적당히 재현해보면 다음과 같이 된다.

 

 

class DataManager
{
    public DataManager()
    {
        LoadMonsters();
    }

    public void LoadMonsters()
    {
        new Monster(어쩌구 저쩌구);
    }
}

class Monster
{
	public Monster()
    {
    	SetDropTable()
    }
    public void SetDropTable()
    {
    	DataManager.Instance.LoadTable(어쩌구 저쩌구)
    }
}

DataManager라는 클래스의 생성자에서 Monster를 만들었고 Monster는 필요한 정보를 세팅하기 위해 또 생성자에서 DataManager를 참조하게 되는 구조라서 계속 생성자가 반복되다가 결국엔 스택 오버플로우가 나게된다.

 

해당 클래스가 만들어지면 자동으로 필요한 정보들이 생성되고 필요한 객체들이 만들어지길 바래서 짠 구조였지만 그렇게 마음대로 되지 않았다.

이 문제를 해결하기 위해 간단하게 LoadMonsters() 에 해당하는 메소드를 외부에서 호출하도록 바꿨지만 다른 방법이 없을지 조언을 구했다.

 

여러 가지 방법이 있겠지만 위에서 내가 쓴 바와 같이 Init()메소드와 같이 초기화용 메소드를 하나 만들고 해당 객체를 관리하는 객체에서 생성 직후 Init을 호출해주는 방법이 있다.

또 하나의 방법은 프로퍼티를 활용해서 내부에 인스턴스를 보관하는 static 변수를 하나 두고 Get을 통해 접근할 때 필요한 초기화까지 같이 진행하는 것이다.

 

조금은 다른 개념인데 DI라는 개념도 있다.

의존성 주입이라는 것으로 객체가 다른 객체에 따라 영향을 받는 것을 의존성이 있다고 하는데 이 의존성을 가진 것을 외부에서 전달해주는 것이다.

예를 들면 먹는다라는 eat(food) 메소드가 있을 때 food에 따라 구워 먹을지 삶아 먹을지 결정된다고 하면 eat은 food에 의존한다. 여기서 food를 eat이 결정하는게 아니라 외부에서 전달해주면 그게 바로 의존성 주입이다.

이런 개념까지 잘 활용해서 다음번에는 스택 오버플로우를 볼 일 없이 클래스 구조를 짜고 초기화를 시킬 예정이다.

 

'부트캠프' 카테고리의 다른 글

정렬 알고리즘  (0) 2023.09.04
팀 콘솔RPG 프로젝트 마무리  (0) 2023.09.01
팀 콘솔 RPG2 (스킬 구현)  (0) 2023.08.29
팀 콘솔RPG 프로젝트  (0) 2023.08.28
콜백함수를 왜 쓰는가?  (0) 2023.08.25