단일 모드 (Qt 구현)
7058 단어 qt 개발
단일 이익 모델은 흔히 사용하는 소프트웨어 디자인 모델로 주로 시스템에 하나의 실례만 있음을 확보하는 데 사용된다. 예를 들어 일반적인 한 프로그램에서 하나의 로그 출력 실례만 있고 한 시스템에서 하나의 데이터베이스 연결 실례만 있기 때문에 이럴 때 단일 사례 모델을 사용하는 것이 매우 적합하다.
간단한 단일 모드
class QSingleton
{
public:
static QSingleton* instance()
{
if (m_pInstance == NULL)
{
m_pInstance = new QSingleton();
}
return m_pInstance;
}
static void Release()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
}
private:
QSingleton(){}
QSingleton(const QSingleton&){}
QSingleton& operator==(const QSingleton&){}
private:
static QSingleton* m_pInstance;
};
//
QSingleton* QSingleton::m_pInstance = NULL;
위에서 실현한 가장 간단한 단일 이익 모델은 게으름뱅이 모델이다. 이른바 게으름뱅이 모델은 프로그램이 필요할 때 구성원 변수의 창설을 하는 것이다. 즉,'시간 지연 불러오기'이다. 이와 상대적으로 굶주린 모델이고 악한 모델은 프로그램이 시작될 때 변수를 만들어야 한다.게으름뱅이 모델은 시간이 공간을 바꾸는 것이고 악한 모델은 공간이 시간을 바꾸는 것이다. 다음과 같은 악한 모델의 간단한 실현을 보면 다음과 같다.
class QSingleton
{
public:
static QSingleton* instance()
{
return m_pInstance;
}
static void Release()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
}
QSingleton(){}
private:
QSingleton(const QSingleton&){}
QSingleton& operator==(const QSingleton&){}
private:
static QSingleton* m_pInstance;
};
//
QSingleton* QSingleton::m_pInstance = new QSingleton;
프로그램이 시작될 때 대상을 만들어야 하기 때문에 단일 클래스의 기본 구조 함수는 때public가 필요하다. 이때 사용자는 단일 클래스의 대상을 만들 수 있기 때문에 단일 모드의 취지를 보장할 수 없다. 하나의 프로그램은 하나의 기본 구조 함수만 있고 우리의 단일 클래스의 기본 구조 함수는 파라미터가 필요할 때 매개 변수를 바꾸는 것은 프로그램 실행 과정에서 구성할 수 있다.이때는 굶주린 사람 모드의 단례 모드를 사용할 수 없다.따라서 게으름뱅이 모델의 단일 모델 실현에 대해 논의해 보겠습니다.위의 간단한 게으름뱅이 모델의 단일 유형 실현은 다음과 같은 단점이 있다.
4
4
4
스레드 보안 단일 모드
class QSingleton
{
public:
static QSharedPointer& instance()
{
QMutexLocker mutexLocker(&m_Mutex);
if (m_pInstance.isNull())
{
m_pInstance = QSharedPointer(new QSingleton());
}
return m_instance;
}
private:
QSingleton(){}
QSingleton(const QSingleton&){}
QSingleton& operator==(const QSingleton&){}
private:
static QMutex m_Mutex;
static QSharedPointer m_pInstance;
};
QMutex QSingleton::m_Mutex;
QSharedPointer QSingleton::m_pInstance;
지능 지침을 통해 구성원 변수를 관리하여 프로그램이 종료될 때 자동으로 메모리를 방출하고 잠금을 통해 m 를 보장합니다pInstance 창설의 유일성은 프로그램이 매번 instance를 호출할 때마다 먼저 자물쇠를 채워야 하기 때문에 프로그램 비용이 크게 증가했다. 다음과 같은 개선 사항을 보면 다음과 같다.
class QSingleton
{
public:
static QSharedPointer& instance()
{
if (m_pInstance.isNull())
{
QMutexLocker mutexLocker(&m_Mutex);
if (m_pInstance.isNull())
m_pInstance = QSharedPointer(new QSingleton());
}
return m_pInstance;
}
private:
QSingleton(){}
QSingleton(const QSingleton&){}
QSingleton& operator==(const QSingleton&){}
private:
static QMutex m_Mutex;
static QSharedPointer m_pInstance;
};
QMutex QSingleton::m_Mutex;
QSharedPointer QSingleton::m_pInstance;
위의 구현은 구성원 변수가 비어 있는지 두 번 검사함으로써 instance 함수를 호출할 때마다 잠그는 효율 문제를 피합니다.
Meyers가 제시한 일례 모델의 실현
class QSingleton
{
public:
static QSingleton& instance()
{
static QSingleton qinstance;
return qinstance;
}
private:
QSingleton(){}
QSingleton(const QSingleton&){}
QSingleton& operator==(const QSingleton&){}
};
상기 단일 모드의 실현에서 instance 함수에서static의 국부 변수를 설명한다. 정적 변수는 프로그램에서 메모리를 한 번만 분배하기 때문에 실례의 유일성을 확보하고 국부 변수로서 프로그램이 처음 호출될 때만 초기화되며 지연 로드도 실현했다. 또한 바늘 변수가 아니기 때문에 프로그램이 끝날 때 자동으로 메모리를 회수하기 때문에 거의 완벽한 실현이다.메모리를 한 번만 분배하는 것이지만 라인의 안전을 확보할 수 있습니까?답은 정해진 것이 아니다. c++의 구조 함수 자체가 라인이 안전하지 않기 때문이다. 우리가 구조 함수 내부에서 구성원 변수나 전역 변수를 초기화할 때 타임슬립이 잘릴 수 있기 때문에 우리가 사용할 때 이 점이 특히 중요하다.