본문 바로가기

 

 네트워크를 배우는 단계에서
DB, Socket 의 객체를
1개만 생성되도록 강제하고
모든 GUI 객체에서 공유하는 
패턴을 기반으로 로직 구현하는 연습한다.

Singleton Pattern(싱글톤 패턴)

: 클래스의 인스턴가 1개만 생성되도록 강제하는 방식

: 1개의 인스턴스를 모든 객체에서 공유하는 방식

 

1. 기본 싱글톤 

1.1. 기본 개념

#include <iostream>

class Singleton
{
private:

    // new 를 사용한 instance 생성을 제한되도록 생성자를 private로 선언 한다.
    Singleton(){};
    ~Singleton() {};
    Singleton(const Singleton& other);

    // 전역 선언, 생성 순서에 기준이 없다.
    static Singleton instance;

public:

    // Singleton static 객체를 반환하는 GetInstance 함수로 접근한다.
    static Singleton& GetInstance()
    {
        return instance;
    }
};

int main(void) 
{
    Singleton& s1 = Singleton::GetInstance();   
}

문제점

: 전역 객체 선언시, 전역으로 선언된 싱글톤 객체의 생성 순서가 명확하지 않다.

싱글톤 객체를 참조하는 전역 객체 및 지역 객체들의 생성 시점이 명확하지 않아 참조 문제가 발생한다. 

// num4가 먼저 될 생성 될 수도 있고 num2가 먼저 될 수도 있다. 알 수 없다.

static int num1 = 0;
static int num2 = 0;
static int num3 = 0;
static int num4 = 0;

2. Dynamic Singleton(동적 싱글톤)

Dynamic(뜻:동적), 늦은 초기화

전역 객체를 포인터로 접근하고, 함수 호출 시 동적으로 할당하여 으로 객체의 생성 시점을 제한한다.

기본 싱글톤의 생성 시점 문제를 해결할 수 있다.

#include <iostream>

class Dynamic_Singleton {
private:
    Dynamic_Singleton() {}
    ~Dynamic_Singleton() {}
    Dynamic_Singleton(const Dynamic_Singleton& ref) {}
    Dynamic_Singleton& operator=(const Dynamic_Singleton& ref) {}

    static Dynamic_Singleton* instance;

public:
    static Dynamic_Singleton* getIncetance() {
        if(instance == NULL)
            instance = new Dynamic_Singleton();
        return instance;
    }
};

Dynamic_Singleton* Dynamic_Singleton::instance = NULL;

int main(void) {
    Dynamic_Singleton* s1 = Dynamic_Singleton::getIncetance();
    Dynamic_Singleton* s2 = Dynamic_Singleton::getIncetance();

    if(s1 == s2)
        std::cout << "O 같습니다." << std::endl;
    else
        std::cout << "X 다릅니다." << std::endl;

    return 0;
}

문제점

"new"로 동적 메모리를 할당을 했기 때문에, 프로그램이 종료될 때 까지 Heap 메모리에 계속 생성되어있다.

싱글톤 클래스의 경우에는 객체가 단 한번만 생성되기 때문에 메모리 누수와 같은 문제에 직면할 가능성도 한없이 낮다.

하지만, Dynamic Singleton 동적 할당이기에 해제하는 함수를 만들거나 소멸자, friend를 이용해서 직접 관리해야 한다.

class Dynamic_Singleton {
	...
    
public:
	...
    
    void Dynamic_Singleton::DestroyInstance()
    {
        if (!instance)
            return;
            
        delete instance;
        instance = nullptr;
    }
}

Static Local Singleton(정적 싱글톤)

#include <iostream>

class Sock_Singleton 
{
private:
    Sock_Singleton() {}
    ~Sock_Singleton() {}
    Sock_Singleton(const Sock_Singleton& ref) {}
    Sock_Singleton& operator=(const Sock_Singleton& ref) {}
public:
    static Sock_Singleton& getIncetance() {
        static Sock_Singleton instance;
        return instance;
    }
};

int main(void) {
    Sock_Singleton& s1 = Sock_Singleton::getIncetance();
    Sock_Singleton& s2 = Sock_Singleton::getIncetance();

    if(&s1 == &s2)
        std::cout << "O 같습니다." << std::endl;
    else
        std::cout << "X 다릅니다." << std::endl;
        
    return 0;
}

 

 

 

 

 

 

 

BasicLike

어? 나 프로그래밍 좋아하네?