[c++] c++에서 싱글턴패턴 사용

TNT·2025년 3월 29일
0

c++ 기초

목록 보기
13/17

이번에는 싱글턴 패턴을 c++에서 사용해보도록 하자

c++ 에서는 생각보다는 크게 차이 나는게 없다 코드 한번 보면 될꺼같다.

먼저 싱글턴하면 생성자와 대입 연산 복사 생성 이 3가지를 막아야한다.
왜냐하면 혼자 유일 클래스로 객체가 존재 해야 하기때문이다.
헤더에 선언 해둔다

TestC.h

class Singleton
{
private:
	/*
    Singleton();
	Singleton(const Singleton& ref);
	Singleton& operator=(const Singleton& ref);
	*/
    
    // c++ 11 부터는 뒤에 delete를 명시를 해서 삭제를 할수가 있다.
	Singleton();
	Singleton(const Singleton& ref) = delete;
	Singleton& operator=(const Singleton& ref) = delete;
};

위에 코드를 보게 된다면

prevate 안에 3개를 선언을 했다.

Singleton(); //기본 생성자

기본 생성자로 클래스 외부에서 객체를 생성 하는걸 막을수가 있다.

Singleton(const Singleton& ref) = delete; // 복사 생성자 생성 제한

클래스의 복사를 막기 위해서 복사 생성자를 delete 하는것으로 객체가 복사되어 싱글톤 패턴을 유지 할수가 있습니다.

Singleton& operator=(const Singleton& ref) = delete; //복사 대입 연산자 생성 제한

설명은 위와 같습니다 역시 복사 대입하는것을 막습니다.

이렇게 생성 하는부분을 막았다면 추가로 호출할수 있는 부분이 필요 합니다.

public:
    static Singleton& getInstance() {
        static Singleton instance; // static 선언
        return instance;

public에 static 으로 선언을 해야한다.
이렇게 된다면 다음에 들어왔을때도 인스턴스로 생성 하는것이 아니고 클래스 자체에 속하기 때문에 해당 함수가 호출 된다면 이후에는 static Singleton instance; 코드에 들어와도 이미 생성 되어있어서 아무 동작 없이 이미 있는 자신을 넘기게 됩니다.
이렇게 하면
1. 늦은 초기화 = 호출 될때만 생성해서 초기화후 보냄
2. 스레드 안전 = c++ 11이상 버전에서는 이런코드를 스레드 안전하게 초기화를 보장 합니다. 여러 스레드에서 동시에 getInstance를 호출해도 1번만 생성이 된다

최종 코드

#include <iostream>
#include <memory>
class Singleton
{
private:
    Singleton() {}
    Singleton(const Singleton& ref) = delete;
    Singleton& operator=(const Singleton& ref) = delete;

public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }

    void ShowString() {
        std::cout << "호출 테스트" << std::endl;
    }
};

이렇게 된다면 singleton 클래스는 1개만 존재 하는 클래스로 사용할수있다.
그러면 다른곳에서 호출 하는 예시까지 첨부

예시

#include "TestC.h"

int main() {

    Singleton& instance1 = Singleton::getInstance();
    Singleton& instance2 = Singleton::getInstance();

    instance1.ShowString();
    instance2.ShowString();

    std::cout << "instance1 주소: " << &instance1 << std::endl;
    std::cout << "instance2 주소: " << &instance2 << std::endl;

    Singleton instance3 = instance1; // 에러 복사 생성 불가능
    instance2 = instance1; //에러 대입 복사 불가능

	return 0;
}


아래에 있는 2가지 경우는 막아 버릴수 가 있다

실행 결과

다른 Singleton을 호출해서 사용한거 같지만 하나의 주소값을 가르키고 있다 즉 같은 클래스를 불러온것
이것으로 매니저의 역활을 하는 클래스를 할수도 있고 다양하게 사용할수있다.

profile
개발

0개의 댓글