프로그래밍 언어/C++

[게임 프로그래머 입문 올인원] 객체지향 : static과 싱글톤 (33강)

순정법사 2023.09.12

E. static 키워드

1. static의 기초

a. static이란?

🌟 변수와 함수의 범위, 수명 및 접근 방법을 변경하는 데 사용하는 키워드

 

2. static의 종류와 관계

a. 정적 변수(Static Variables)

🌟 함수 내부에서 선언된 지역 변수를 "정적 변수"로 만듦

 

  • 변수는 프로그램이 처음 실행될 때 한 번 초기화되어 여러번 호출되어도 초기화 되지 않음
  • 정적 변수는 함수의 범위를 벗어나도 값이 유지됨

 

⏳ 예제 : 정적 변수

void countCalls() {
    static int counter = 0; // 정적 변수
    counter++;
    cout << "함수가 " << counter << "번 호출되었습니다." << endl;
}

int main() {
    countCalls(); // 출력: "함수가 1번 호출되었습니다."
    countCalls(); // 출력: "함수가 2번 호출되었습니다."

    return 0;
}

 

b. 정적 멤버 변수(Static Member Variables)

🌟 클래스 내에서 선언된 정적 멤버 변수는 모든 클래스 객체가 공유하는 변수

👉 즉, 클래스의 모든 인스턴스 간에 동일한 값이 유지

 

  • 클래스 이름을 통해 접근, 객체의 상태에 관계없이 동일한 값에 접근함
  • static임을 명시하기 위해 접두사로 s_ 사용 

 

⏳ 예제 : 정적 멤버 변수

class MyClass {
public:
    static int count; // 정적 멤버 변수
};

int MyClass::count = 0; // 정적 멤버 변수 초기화

int main() {
    MyClass obj1;
    MyClass obj2;

    MyClass::count++; // 정적 멤버 변수에 접근

    cout << "count: " << MyClass::count << endl; // 출력: "count: 1"

    return 0;
}

 

c. 정적 멤버 함수(Static Member Functions)

🌟 클래스 내에서 선언된 정적 멤버 함수는 객체의 인스턴스에 속하지 않고 클래스 자체에 속하는 함수

 

  • 정적 함수는 객체의 상태에 의존하지 않고 호출
  • 클래스와 관련된 유틸리티 함수 또는 객체의 상태와 무관한 동작을 수행하는 데 사용

 

⏳ 예제 : 정적 함수

class MathUtils {
public:
    static double square(double num) {
        return num * num;
    }
};

int main() {
    double result = MathUtils::square(5.0); // 정적 함수 호출
    cout << "5의 제곱은 " << result << "입니다." << endl;

    return 0;
}

 

d. Static과 멤버 변수/함수의 관계

쉽게 말해 static 키워드가 붙으면 제품과 관계 없고 청사진과 관련이 생김

 

정적 멤버 변수는 메모리가 stack 영역에 생성되지 않음 (일반 멤버 변수는 stack영역)

💥 따라서 정적 멤버 함수가 일반 stack 영역에 있는 비정적 멤버 (일반 멤버)를 사용할 수 없음

 

⏳ 예제

#include <iostream>
using namespace std;

struct Marine {
public: 
    //특정 마린 객체와 연관
    void TakeDamage(int damage) {
        hp -= damage;
    }

    //특정 마린 객체와 무관 
    //그냥 코드 관리 차원에서 사용하는 것
    static void SetAttack(int value) {
        //hp = 40;    비정적 멤버 참조는 특정 객체에 상대적이여야 함
        attack = value;
    }

public:
    //특정 마린 객체와 연관
    int hp = 40;

    //특정 마린 객체와 무관 
    static int attack;  //더이상 stack 영역에 있는 메모리가 아님 
};

int Marine::attack = 6; //공공재 데이터 

int main() {
    Marine::SetAttack(10)
}

 

 

3. static 예제

a. Player의 id를 관리하는 예제

⏳ 예제 1 : 정적 멤버 변수로 관리하기

#include <iostream>
using namespace std;

class Player {
public:
	Player() {
		//id를 1씩 늘리기
		id = s_idGenerator++;
	}
public : 
	int id;
	static int s_idGenerator;	//static임을 명시하기 위해 s_사용 
};

int Player::s_idGenerator = 1;

int main() {

	Player p1;	//1
	Player p2;	//2
	Player p3;	//3

	cout << Player::s_idGenerator << endl;
}

✨ 실행결과

4

  

⏳ 예제 2 : 정적 변수로 관리하기

#include <iostream>
using namespace std;

int GenerateId() {
	static int s_id = 10;
	return s_id++;
}

int main() {
	cout << GenerateId() << endl;
	cout << GenerateId() << endl;
}

✨ 실행결과

10
11

 

 

 


F. 싱글톤(Singleton)

1. 디자인 패턴

a. 디자인 패턴이란?

어떤식으로 코드를 구성해야 좋을지를 다루는 학문

ex) 싱글톤, 옵저버, 콤포넌트

 

 

2. 싱글톤 기초

a. 싱글톤이란?

🌟 정말 딱 1개만 존재하고 어디서든 사용할 수 있는 클래스 

 

static 키워드로 선언하고 객체의 주소를 반환해 딱 1개만 사용할 수 있도록 해줌

 

b. 싱글톤 생성

대표적으로 [매니저] 클래스에 사용

 

⏳ 예제 : 싱글톤 매니저 클래스 사용법

#include <iostream>
using namespace std;

//싱글톤으로 생성
class UserManager {
public:
	static UserManager* GetInstance() {
		static UserManager um;
		return &um;
	}

public: 
	void AddUser() { _userCount++; }
	int GetUserCount() { return _userCount; }

private : 
	int _userCount = 0;
};

int main() {
	for(int i=0; i<10; i++){
    	//GetInstance()로 UserManager의 객체를 받아 그 객체의 유저 수를 늘려줌
		UserManager::GetInstance()->AddUser();	
	}

	//동일하게 유저의 수를 리턴해줌
	cout << UserManager::GetInstance()->GetUserCount() << endl;
}

 

👉 싱글톤 객체로 데이터를 관리하는 방법을 보여줌

 

💙 #define 키워드

위 코드에서 UserManager::GetInstance()를 매번 호출하기 귀찮으니까
#define Get_Manager (UserManager::GetInstance())코드로 선언해주고
대신 Get_Manager로 치환해서 사용할 수 있음!

...

#define Get_Manager (UserManager::GetInstance())

int main() {
	for(int i=0; i<10; i++){
		Get_Manager->AddUser();
	}

	cout << Get_Manager->GetUserCount() << endl;
}​

 

📌 Notice!

매니저 클래스는 전역 변수이건, 싱글톤이건 뭐건 전역으로 관리하는게 일반적!!
나중에 프로젝트를 관리할때 너무 완벽하게 코드를 짜려고 하지는 말자!!

 

 

 


출처 : https://www.inflearn.com/course/%EA%B2%8C%EC%9E%84-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8-%EC%9E%85%EB%AC%B8-%EC%98%AC%EC%9D%B8%EC%9B%90-rookiss#curriculum

 

[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버 -

어디부터 시작할지 막막한 게임 프로그래밍 입문자를 위한 All-In-One 커리큘럼입니다. C++, 자료구조/알고리즘, STL, 게임 수학, Windows API, 게임 서버 입문으로 이어지는 알찬 커리큘럼으로 게임 프

www.inflearn.com