수색…


비고

싱글은 클래스가 하나의 인스턴스 만이 있고 액세스의 글로벌 지점을 제공하기 위해 설계되었습니다. 하나의 인스턴스 또는 편리한 전역 액세스 지점 만 있으면되지만 둘 다 필요하지 않은 경우에는 싱글 톤으로 전환하기 전에 다른 옵션을 고려하십시오.

전역 변수 코드에 대한 추론을 어렵게 만듭니다. 예를 들어, 호출 함수 중 하나가 Singleton에서 수신하는 데이터에 만족하지 못하면 먼저 먼저 싱글 톤 불량 데이터를 제공하는 대상을 추적해야합니다.

싱글 톤은 또한 서로 결합 되는 코드의 두 구성 요소를 설명하는 데 사용되는 용어 인 커플 링 을 권장하므로 각 구성 요소가 자체 포함을 측정하는 수준을 줄입니다.

싱글 톤은 동시성이 없다. 클래스에 전역 액세스 지점이 있으면 모든 스레드가 액세스 할 수 있으므로 교착 상태와 경쟁 조건이 발생할 수 있습니다.

마지막으로, 게으른 초기화는 잘못된 시간에 초기화 될 경우 성능 문제를 일으킬 수 있습니다. lazy 초기화를 제거하면 다형성 (Subclass 참조)과 같은 Singleton의 흥미로운 기능을 제거합니다.

출처 : Robert Nystrom의 게임 프로그래밍 패턴

게으른 초기화

이 예제는 Q & A 섹션에서 제거되었습니다. http://stackoverflow.com/a/1008289/3807729

파괴 된 싱글 톤으로 평가 된 게으른 평가를위한 간단한 디자인은이 기사를 참조하십시오.
어떤 사람이 C ++에서 Singleton 샘플을 제공 할 수 있습니까?

고전 게으른 평가하고 올바르게 파괴 싱글 톤.

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                                  // Instantiated on first use.
            return instance;
        }
    private:
        S() {};                   // Constructor? (the {} brackets) are needed here.

        // C++ 03
        // ========
        // Dont forget to declare these two. You want to make sure they
        // are unacceptable otherwise you may accidentally get copies of
        // your singleton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement

        // C++ 11
        // =======
        // We can use the better technique of deleting the methods
        // we don't want.
    public:
        S(S const&)               = delete;
        void operator=(S const&)  = delete;

        // Note: Scott Meyers mentions in his Effective Modern
        //       C++ book, that deleted functions should generally
        //       be public as it results in better error messages
        //       due to the compilers behavior to check accessibility
        //       before deleted status
};

싱글 톤 (singleton)을 사용할시기에 대한이 기사를 참조하십시오.
싱글 톤 : 어떻게 사용해야합니까?

초기화 순서 및 처리 방법에 대한이 두 문서를 참조하십시오.
정적 변수 초기화 순서
C ++ 정적 초기화 순서 문제 찾기

수명에 대해 설명하는이 기사를 참조하십시오.
C ++ 함수에서 정적 변수의 수명은 어떻게됩니까?

싱글 톤에 대한 스레딩 관련 내용을 설명하는 다음 기사를 참조하십시오.
GetInstance 메서드의 정적 변수로 선언 된 Singleton 인스턴스

C ++에서 이중 잠금이 작동하지 않는 이유를 설명하는이 기사를 참조하십시오.
C ++ 프로그래머가 알아야 할 모든 정의되지 않은 동작은 무엇입니까?

서브 클래스

class API
{
public:
    static API& instance();
    
    virtual ~API() {}
    
    virtual const char* func1() = 0;
    virtual void func2() = 0;
    
protected:
    API() {}
    API(const API&) = delete;
    API& operator=(const API&) = delete;
};

class WindowsAPI : public API
{
public:
    virtual const char* func1()  override { /* Windows code */ }
    virtual void func2() override { /* Windows code */ }    
};

class LinuxAPI : public API
{
public:
    virtual const char* func1() override { /* Linux code */ }
    virtual void func2() override { /* Linux code */ }    
};

API& API::instance() {
#if PLATFORM == WIN32
    static WindowsAPI instance;
#elif PLATFORM = LINUX
    static LinuxAPI instance;
#endif
    return instance;
}

이 예제에서 간단한 컴파일러 스위치는 API 클래스를 적절한 하위 클래스에 바인딩합니다. 이 방법으로 API 는 플랫폼 특정 코드에 결합되지 않고 액세스 될 수 있습니다.

thread-safe Singeton

C ++ 11

C ++ 11 표준은 함수 범위 객체의 초기화가 동기화 된 방식으로 초기화된다는 것을 보장합니다. 지연 초기화를 사용하여 스레드 안전 싱글 톤을 구현하는 데 사용할 수 있습니다.

class Foo
{
public:
    static Foo& instance()
    {
        static Foo inst;
        return inst;
    }        
private:
    Foo() {}
    Foo(const Foo&) = delete;
    Foo& operator =(const Foo&) = delete;
};

정적 deinitialization 안전 싱글 톤.

당신이 싱글은 더 이상 싱글 톤을 사용하지 그것을 필요로하는 모든 정적 객체까지 파괴되지 않는다는 것을 보장 할 수 있어야합니다 여러 정적 객체와 시간이있다.

이 경우 std::shared_ptr 는 정적 소멸자가 프로그램의 끝에서 호출되는 경우에도 모든 사용자에 대해 싱글 톤 을 유지하는 데 사용할 수 있습니다.

class Singleton
{
public:
    Singleton(Singleton const&) = delete;
    Singleton& operator=(Singleton const&) = delete;

    static std::shared_ptr<Singleton> instance()
    {
        static std::shared_ptr<Singleton> s{new Singleton};
        return s;
    }

private:
    Singleton() {}
};

참고 : 이 예제는 Q & A 섹션의 대답으로 나타납니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow