싱글 톤 템플리트가 실제로 싱글 톤이 아닐 수도 있다는 말을 들었습니다. 하나 이상의 객체를 만드는 방법이 있습니다. 내가 그것을 고치는 방법을 물었을 때, 나는 무시 당했다. 그래서 여기에 와서 왜 내 싱글 톤 템플릿 클래스가 정말로 싱글 톤인지 묻습니다.내 싱글 톤 템플릿이 실제로 싱글 톤입니까?
class Console : public Singleton<Console>
{
};
싱글 톤 템플리트가 실제로 싱글 톤이 아닐 수도 있다는 말을 들었습니다. 하나 이상의 객체를 만드는 방법이 있습니다. 내가 그것을 고치는 방법을 물었을 때, 나는 무시 당했다. 그래서 여기에 와서 왜 내 싱글 톤 템플릿 클래스가 정말로 싱글 톤인지 묻습니다.내 싱글 톤 템플릿이 실제로 싱글 톤입니까?
class Console : public Singleton<Console>
{
};
사용하십시오 지역 정적 변수 구현하는 싱글 톤 패턴 : 훨씬 적은 코드와는 별도로
template <class T>
class Singleton
{
static T* getInstancePtr()
{
static T instance; // <-- HERE
return &instance;
}
};
, 또한 스레드 안전 보장됩니다. Singleton<X>::getInstancePtr()
에 대한 첫 번째 호출에서 생성되고 연속 호출은 하나의 인스턴스를 가져옵니다. 당신이 스레드 당 하나 개의 인스턴스를 원하는 경우
또는 대신 thread_local
사용할 수 있습니다
template <class T>
class Singleton
{
static T* getInstancePtr()
{
thread_local T instance; // <-- HERE
return &instance;
}
};
는 싱글 왜 당신은 보장 할 수있는 한 가지 간단한 이유 예정이다 스레드 - 안전 - : 내가 원하는
#ifndef SINGLETON_H_
#define SINGLETON_H_
template <class T>
class Singleton
{
private:
static T* instance;
protected:
Singleton<T>()
{
}
public:
static T* getInstancePtr()
{
if (instance == 0)
instance = new T();
return instance;
}
};
template <class T> T* Singleton<T>::instance = 0;
#endif
이것은 다음 클래스에 의해 상속 그래서 같은 싱글이 될 수 있습니다 .
두 개 이상의 스레드가 getInstancePtr을 동시에 호출하면 스레드 스와핑에 따라 두 개 이상의 인스턴스가 종료 될 수 있습니다.
OP의 질문은 멀티 스레딩과 관련이 없으며 싱글 톤은 멀티 스레딩에 고유하지 않습니다. – phonetagger
기본 생성자는 protected
입니다. 파생 클래스가 액세스 할 수 있으므로 컴파일됩니다.
Console c1, c2;
다른 사람들의 의견을 답변으로 다시 게시하지 마십시오. –
@ 니콜라이 - 왜 그게? –
@Charles Q가 편집되었습니다. 정의가 있습니다. @ Nikolai'std :: string str;'을 작성한 적이 있습니까? 나도 했어. – jrok
다중 스레드 환경에서 작업하려면 다른 해결책이 필요합니다. 특정 언어 기능을 사용하여 다중 스레드가있는 상태에서 하나의 오브젝트 인스턴스 만 작성되도록해야합니다. 보다 일반적인 솔루션 중 하나는 Double-Check Locking 관용구를 사용하여 개별 스레드가 동시에 단일 인스턴스의 새 인스턴스를 작성하지 못하게하는 것입니다.
OP의 질문은 멀티 스레딩과 관련이 없으며 싱글 톤은 멀티 스레딩에도 고유하지 않습니다. – phonetagger
멀티 스레딩의 문제점 이외에도 두 가지 인스턴스를 만들 수있는 경우가있었습니다. 그래서
Console c1;
처럼
class Console : public Singleton<Console>
{
};
아래의 클래스 콘솔을 초기화하는에 의하여 나는 콘솔의 두 인스턴스, 싱글 톤 클래스 내에서 개최 된 인스턴스 포인터의 하나는 C1 개체 자체 내에서 하나 결말이었다. 싱글 톤 클래스를 다음과 같이 변경하여이 문제를 해결했습니다.
#ifndef SINGLETON_H_
#define SINGLETON_H_
template <class T>
class Singleton
{
private:
static T* instance;
protected:
Singleton<T>()
{
if (instance == 0)
instance = static_cast<T*>(this);
}
public:
static T* getInstancePtr()
{
return instance;
}
};
template <class T> T* Singleton<T>::instance = 0;
#endif
멀티 스레딩 문제 외에도, 이제는 싱글 톤 클래스가 여러 인스턴스를 생성 할 가능성이 적습니다.
개인적인 생성자와 소멸자를 만들기 위해 동일한 싱글 톤 템플릿을 사용했지만 사용자에게 맡깁니다. 사용자는 싱글 톤 클래스와 친구가되어야하지만, 원하는대로 가깝기 때문에 싱글 톤으로 사용할 수 있습니다. 아직 스레드 세이프가 아니지만 다중 인스턴스 문제를 '해결'합니다.
당신이'콘솔 C1, C2를 컴파일 해봤;'? –
나는 방금 단일 인스턴스를 우회하는 한 가지 방법을 발견했습니다.콘솔 c1로 콘솔을 초기화하면; 나는 Singleton 클래스의 인스턴스 포인터에 c1의 Console 인스턴스와 Console의 두 번째 인스턴스를 가지고있다. – ctor