[C++] 객체 지향 프로그래밍 - static과 싱글톤

Taeil Nam·2022년 10월 26일
0

C++

목록 보기
6/13
post-thumbnail

static

  • 클래스 내부에서 static 키워드를 사용하여 정적 멤버 함수, 정적 멤버 변수를 선언할 수 있음.

정적 멤버 변수

  • 객체 별로 할당되지 않고, 클래스의 모든 객체가 공유하는 멤버 변수.
  • 해당 클래스의 모든 객체에 대해 하나의 데이터로만 관리 가능.
  • 클래스 외부에서 초기화 가능.
  • 클래스의 모든 객체에 적용되는 전역 변수라고 생각하면 됨.

정적 멤버 함수

  • 클래스의 객체를 생성하지 않고, 클래스 이름만으로 함수 호출 가능.
  • 정적 멤버 변수만 사용 가능.

예제 코드

#include <iostream>

using namespace std;

class Marine
{
public:
	// 동적 멤버 함수 : 특정 Marine 객체와 연관됨.
	void TakeDamage(int damage)
	{
		_hp -= damage;
	}

	// 정적 멤버 함수 : 특정 Marine 객체와 무관함.
	static void UpgradeDamage(int value)
	{
		_damage += value;
	}

public:
	// 동적 멤버 변수 : 특정 Marine 객체와 연관됨.
	int _hp = 40;

	// 정적 멤버 변수 : 특정 Marine 객체와 무관함.
	static int _damage; 
};

// 정적 멤버 변수 = 클래스 외부에서 초기화.
// 모든 Marine 객체에 적용됨.
int Marine::_damage = 6;

int main()
{
	Marine m1;
	Marine m2;
	
    // 초기화된 정적 멤버 변수 _damage 값 출력.
	cout << "m1 Damage = " << m1._damage << endl;
	cout << "m2 Damage = " << m2._damage << endl;
	cout << endl;

	// 정적 멤버 변수 _damage 값 변경 후 결과 출력.
	Marine::_damage = 7; // 모든 Marine 객체에 적용됨.
	cout << "m1 Damage = " << m1._damage << endl;
	cout << "m2 Damage = " << m2._damage << endl;
	cout << endl;

	// 정적 멤버 함수 UpgradeDamage(1) 호출 후 결과 출력.
	Marine::UpgradeDamage(1); // 모든 Marine 객체에 적용됨.
	cout << "m1 Damage = " << m1._damage << endl;
	cout << "m2 Damage = " << m2._damage << endl;
	cout << endl;

	return 0;
}

싱글톤 (Singleton)

  • 디자인 패턴 중 하나.
  • 디자인 패턴 : 객체 지향 프로그래밍 설계를 할 때, 자주 발생하는 문제들을 피하기 위해 사용되는 패턴.
  • 싱글톤 : 정말 딱 1개만 존재하고 어디서든 사용할 수 있는 [매니저] 클래스.
  • 관리 목적으로 자주 사용됨.

예제 코드

#include <iostream>

using namespace std;

class UserManager
{
public:
	static UserManager* GetInstance()	// 정적 멤버 함수 선언.
	{
		static UserManager um;	// UserManager 객체 um을 정적 멤버 변수로 생성.
		return &um;	// um의 메모리 주소 반환. (정적 멤버 변수라서 Stack이 아닌 Data 영역에 메모리가 할당되므로 반환해도 괜찮음.)
	}

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

private:
	int _userCount = 0;
};

int main()
{
	for (int i = 0; i < 10; i++)
		UserManager::GetInstance()->AddUser();

	cout << UserManager::GetInstance()->GetUserCount();

	return 0;
}
  • UserManager::GetInstance() 함수로 UserManager의 객체 um의 메모리 주소를 반환받고, 그 객체를 사용하여 내부 멤버 변수들을 사용하는 방식.
  • UserManager의 객체 um은 Data 메모리 영역에 할당되고 고정된 메모리 주소를 가짐. (Stack 메모리 영역이 아니기 때문에 해당 메모리 주소를 반환해도 괜찮고, 고정된 메모리 주소 1개만 계속 사용함)

0개의 댓글