본문 바로가기
C++

C++ Singleton, Recursive, State - 24.11.27

by 부어잉 2024. 11. 27.
반응형

Design Pattern - 생성, 구조, 행동 패턴

그 중 생성 패턴 중에서 가장 활용되는 것이 바로 싱글턴이다.

 

*Singleton

 - 클래스의 인스턴스를 오로지 하나만 생성해서 전역적으로 접근 가능하게 만드는 것이 핵심.

 - 단 하나의 인스턴스만을 가지게 되는 것을 보장해준다.

 - 클래스의 객체가 복사가 되면 안되고, 외부에서 객체가 생성되거나 소멸이 안되도록 막아줘야 한다.

 

template<typename T>
class Singleton
{
    private : 
    	//상속받을 일이 없기에, 생성자,소멸자를 private에 두어 사용해도 된다.
        //외부에서 객체 생성, 삭제를 막아서 프로그래머의 실수를 줄일 수 있다.
    	Singleton()
        {
        	cout<<"싱글톤 인스턴스 생성"<<endl;
        }
        ~Singleton()
        {
        }
        Singleton(const Singleton&) = delete; //대입 연산을 막는다.
        Singleton& operator = (const Singleton&) = delete;	//객체 연산자를 막는다.

    public:
    	//정적 지역 변수를 이용.
    	static Singleton& GetInstance()
        {
        	static T instance;
            return instance;
        }
        void Show()
        {
        	cout<<"난 싱글톤이야"<<endl;
        }
};

 

⁕ Recursive ( 재귀 )

- 자기 자신을 계속해서 호출하는 것.

- 복잡한 문제를 더 단순한 하위 문제로 쪼개서 해결할 때 사용.

 

* 재귀 함수

- 재귀함수는 반드시 하나 이상의 종료 조건(기저 조건)이 있어야 한다.

     그렇지 않을 경우, 계속해서 무한 루프를 돌게 된다.

- 재귀 단계 : 함수가 자기 자신을 호출하는 단계. 이 단계에서 더 작은 하위 문제로 분해가 된다.

- 예 ) 피보나치 수열, 하노이의 탑, 팩토리얼 등

 

int Factorial(int n)
{
    //종료조건
    if(n <= 1)
    {
    	return 1;
    }
    //2.재귀 단계
    return n * Facrotial(n-1);

}

 

* 위 함수의 호출 단계

1. 첫 번째 호출 : 함수는 Factorial(3)에서 종료 조건을 확인 후,

 ㄴ n 이 1보다 크기때문에 3 * Factorial(2)를 리턴.

2. 두 번째 호출 : Factorial(2)호출 

 ㄴ n이 1보다 크기 때문에 2 * Factorial(1) 리턴

3. 세 번째 호출 : Factorial(1)

 ㄴ 종료 조건을 만족하므로 1을 반환

 Factorial(1) - > 1 반환

 Factorial(2) - > 2 * 1 반환

 Factorial(3) - >  3 * 2  반환

 

특징

- 성능이 for문보다 떨어질 수 있다.

- 메모리 사용량은 적지만, 복잡한 문제를 표현하는데 있어서는 어려움이 있을 수 있다.

- 호출한 함수가 다음 함수가 반환이 될때까지 계속 기다린다. 

- 현재 함수의 상태가 스택에 저장되고, 기저 조건으로 반환이 되면 스택으로 값이 전달된다.

- 재귀 호출이 너무 깊어지면 스택 오버 플로우가 발생한다.

 

 

⁕State

- 클래스를 활용하여 상태를 캡슐화를 하고, 상태간의 전환을 쉽게 처리하기 위해 사용된다.

- 클래스를 사용하는 것이 상태 패턴의 주요한 특징을 살리는데 도움이 됨.

 

class CState
{
public:
    virtual void EnterState() = 0;
    virtual void InputState() = 0;
    virtual void Update() = 0;
    virtual void ExitState() = 0;
};

class CJumpState : public CState
{
	void EnterState() override
    {
    	cout<<"점프 상태 진입"<<endl;
    }
    void InputEvent() override
    {
    	cout<<"점프 상태에서 키 입력을 받음"<<endl;
    }
    void Update() override
    {
    	cout<<"점프중에 위치가 변경"<<endl;
    }
    void ExitState() override
    {
    	cout<<" 점프 끝"<<endl;
    }
};

 

 

728x90