내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
소프트웨어 개발에서 디자인 패턴은 특정 문제에 대한 입증된 솔루션으로 개발자가 보다 일관되고 재사용 가능하며 유지 관리 가능한 방식으로 소프트웨어를 구축하는 데 도움이 됩니다. 싱글톤 패턴은 가장 기본적이고 널리 사용되는 디자인 패턴 중 하나입니다. 이 패턴은 클래스에 인스턴스가 하나만 있도록 하고 이 인스턴스를 얻기 위한 전역 액세스 지점을 제공합니다.이 기사에서는 기본 구현부터 스레드 안전 버전, 스마트 포인터 및std::call_once
) 응용 프로그램을 작성하고 독자들에게 포괄적이고 실용적인 가이드를 제공하기 위해 노력합니다.
싱글톤 패턴의 핵심 아이디어는 클래스에 인스턴스가 하나만 있도록 하고 전역 액세스 지점을 제공하는 것입니다. 이 모드는 리소스(예: 구성 파일 판독기, 로거, 데이터베이스 연결 풀 등)에 대한 액세스를 제어해야 할 때 유용합니다. 싱글톤 패턴의 핵심은 다음과 같습니다.
getInstance()
, 클래스의 유일한 인스턴스를 얻는 데 사용됩니다.먼저 스레드 안전성 문제를 고려하지 않고 간단한 싱글톤 패턴 구현을 살펴보겠습니다.
#include <iostream>
class Singleton {
private:
// 私有构造函数,防止外部实例化
Singleton() {}
// 私有拷贝构造函数和赋值操作符,防止拷贝
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
// 静态实例
static Singleton* instance;
public:
// 静态方法,返回类的唯一实例
static Singleton* getInstance() {
if (!instance) {
instance = new Singleton();
}
return instance;
}
// 示例方法
void doSomething() {
std::cout << "Doing something..." << std::endl;
}
// 析构函数(通常是protected或public,取决于是否需要外部delete)
~Singleton() {
std::cout << "Singleton destroyed." << std::endl;
}
};
// 初始化静态实例
Singleton* Singleton::instance = nullptr;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
if (s1 == s2) {
std::cout << "s1 and s2 are the same instance." << std::endl;
}
s1->doSomething();
// 注意:在多线程环境下,上述实现可能存在安全问题
// 通常不推荐手动删除单例对象,除非有特别理由
// delete Singleton::instance; // 谨慎使用
return 0;
}
다중 스레드 환경에서 위 구현으로 인해 여러 스레드가 동시에 들어갈 수 있습니다.getInstance()
메서드를 사용하여 인스턴스를 여러 번 생성합니다.이 문제를 해결하기 위해 뮤텍스 잠금(예:std::mutex
) 스레드 안전을 보장하기 위해:
#include <mutex>
#include <iostream>
class Singleton {
private:
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* instance;
static std::mutex mtx;
public:
static Singleton* getInstance() {
std::lock_guard<std::mutex> lock(mtx);
if (!instance) {
instance = new Singleton();
}
return instance;
}
void doSomething() {
std::cout << "Doing something..." << std::endl;
}
~Singleton() {
std::cout << "Singleton destroyed." << std::endl;
}
};
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
// main函数保持不变
싱글톤 객체(즉, 프로그램 종료 시 자동으로 소멸됨)의 수명 주기를 자동으로 관리하기 위해 스마트 포인터(예:std::unique_ptr
) 원시 포인터 대신:
#include <memory>
#include <mutex>
#include <iostream>
class Singleton {
private:
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static std::unique_ptr<Singleton> instance;
static std::mutex mtx;
public:
static Singleton& getInstance() {
std::lock_guard<std::mutex> lock(mtx);
if (!instance) {
instance = std::make_unique<Singleton>();
}
return *instance;
}
void doSomething() {
std::cout << "Doing something..." << std::endl;
}
// 析构函数被智能指针管理,无需手动调用
~Singleton() {
std::cout << "Singleton destroyed." << std::endl;
}
// 禁止拷贝和移动
Singleton(Singleton&&) = delete;
Singleton& operator=(Singleton&&) = delete;
};
std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
// 注意这里返回的是引用,无需使用指针
Singleton& s1 = Singleton::getInstance();
Singleton& s2 = Singleton::getInstance();
if (&s1 == &s2) {
std::cout << "s1 and s2 are the same instance." << std::endl;
}
s1.doSomething();
// 程序结束时,智能指针会自动销毁Singleton实例
return 0;
}
std::call_once
최적화C++11부터 시작하여,std::call_once
다중 스레드 환경에서도 함수가 한 번만 호출되도록 보다 효율적이고 간결한 방법을 제공합니다. 이 기능을 사용하여 싱글톤 패턴 구현을 더욱 최적화할 수 있습니다.
#include <memory>
#include <mutex>
#include <iostream>
#include <once.h> // 注意:实际上应使用#include <mutex>中的std::call_once
class Singleton {
private:
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static std::unique_ptr<Singleton> instance;
static std::once_flag onceFlag;
static void createInstance() {
instance = std::make_unique<Singleton>();
}
public:
static Singleton& getInstance() {
std::call_once(onceFlag, createInstance);
return *instance;
}
void doSomething() {
std::cout << "Doing something..." << std::endl;
}
// 析构函数和移动操作符的禁用同上
};
std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::once_flag Singleton::onceFlag;
// main函数保持不变
참고: 위 코드에서는 잘못 인용했습니다.#include <once.h>
, 실제로 사용해야합니다<mutex>
헤더 파일에std::once_flag
그리고std::call_once
。
싱글톤 패턴은 C++에서 매우 유용한 디자인 패턴으로, 클래스에 인스턴스가 하나만 있고 전역 액세스 지점을 제공합니다. 그러나 싱글톤 패턴을 구현할 때, 특히 멀티스레드 환경에서 스레드 안전성 문제에 주의해야 합니다.뮤텍스 잠금, 스마트 포인터 및std::call_once
최신 C++ 기능을 사용하면 싱글톤 패턴을 보다 안전하고 효율적으로 구현할 수 있습니다.
싱글톤 패턴을 설계할 때 싱글톤 객체의 수명주기 관리(프로그램 종료 시 자동으로 소멸되어야 하는지 여부), 지연 로딩 허용 여부(즉, 생성 지연)와 같은 몇 가지 추가 요소를 고려해야 합니다. 처음 사용될 때까지 인스턴스) 등 또한 경우에 따라 다중 인스턴스 패턴(클래스 인스턴스 수를 제어하지만 특정 상한을 초과하지 않음) 또는 컨텍스트 기반 싱글톤 패턴( 이는 다른 컨텍스트에 따라 다른 값을 반환합니다).
이 기사가 독자들이 C++의 싱글톤 패턴을 더 잘 이해하고 실제 프로젝트에서 유연하게 사용하는 데 도움이 되기를 바랍니다.