C++
싱글 톤 디자인 패턴
수색…
비고
싱글은 클래스가 하나의 인스턴스 만이 있고 액세스의 글로벌 지점을 제공하기 위해 설계되었습니다. 하나의 인스턴스 또는 편리한 전역 액세스 지점 만 있으면되지만 둘 다 필요하지 않은 경우에는 싱글 톤으로 전환하기 전에 다른 옵션을 고려하십시오.
전역 변수 는 코드에 대한 추론을 어렵게 만듭니다. 예를 들어, 호출 함수 중 하나가 Singleton에서 수신하는 데이터에 만족하지 못하면 먼저 먼저 싱글 톤 불량 데이터를 제공하는 대상을 추적해야합니다.
싱글 톤은 또한 서로 결합 되는 코드의 두 구성 요소를 설명하는 데 사용되는 용어 인 커플 링 을 권장하므로 각 구성 요소가 자체 포함을 측정하는 수준을 줄입니다.
싱글 톤은 동시성이 없다. 클래스에 전역 액세스 지점이 있으면 모든 스레드가 액세스 할 수 있으므로 교착 상태와 경쟁 조건이 발생할 수 있습니다.
마지막으로, 게으른 초기화는 잘못된 시간에 초기화 될 경우 성능 문제를 일으킬 수 있습니다. lazy 초기화를 제거하면 다형성 (Subclass 참조)과 같은 Singleton의 흥미로운 기능을 제거합니다.
게으른 초기화
이 예제는 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 표준은 함수 범위 객체의 초기화가 동기화 된 방식으로 초기화된다는 것을 보장합니다. 지연 초기화를 사용하여 스레드 안전 싱글 톤을 구현하는 데 사용할 수 있습니다.
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 섹션의 대답으로 나타납니다.