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!
매니저 클래스는 전역 변수이건, 싱글톤이건 뭐건 전역으로 관리하는게 일반적!!
나중에 프로젝트를 관리할때 너무 완벽하게 코드를 짜려고 하지는 말자!!
'프로그래밍 언어 > C++' 카테고리의 다른 글
[자료형(data type)] C++ 파생형 공용체와 열거체 총정리 (0) | 2023.09.13 |
---|---|
[자료형(data type)] C++ 파생형 구조체 총정리 (0) | 2023.09.13 |
[게임 프로그래머 입문 올인원] 객체지향 : 연산자 오버로딩 (32강) (0) | 2023.09.12 |
[게임 프로그래머 입문 올인원] 객체지향 : 멤버 변수 초기화 (31강) (0) | 2023.09.11 |
[게임 프로그래머 입문 올인원] 객체지향 : OOP 3대 요소 / 상속성, 은닉성, 다형성 (28, 29, 30강) (0) | 2023.09.11 |