2026-03-26(목) vector, enum, 싱글톤

조범근·2026년 3월 26일

TIL

목록 보기
26/81

C++ Week 5

팀원분들 구현한 코드를 보고 많이 배웠다.

Study

팀프로젝트, 알고리즘 1 문제


Today I Learned


vector.push_back( x );과 vector[i] = x; 개념 확실하게 알기

Overview

vector[i] = x;vector.reserve(n) 이렇게 capacity만 늘려두면 값을 직접 넣는 것은 불가능 하다.
이렇게 값을 넣고 싶으면 resize로 사이즈를 할당하고 쓴다.

vector.push_back는 할당된 공간이 없을때 그냥 자유롭게 쓰기도 하지만, 값이 크고 지정된 크기가 있으면 reserve를 이용하거나 애초에 선언할때 크기를 할당해주고 쓴다.

vector[i] = x; -> vector.resize나 선언시 값을 할당하는 직접적인 size가 있어야 가능

vector.push_back -> 할당된 공간이 없을때 자유롭게 가능, reserve나 선언할때 크기 할당 해주고 쓰기 가능.





enum

Overview

열거형(Enum, Enumeration)는 서로 연관된 정수형 상수들의ㅡ 집합에 이름을 붙여 관리하는 사용자 정의 데이터 타입이다. 이렇게 설명하면 어려워보이지만 예시를 보면 어렵지 않다.

enum EState {
    IDLE,    // 0
    WALK,    // 1
    RUN,     // 2
    ATTACK   // 3
};

EState playerState = IDLE;

if (playerState == ATTACK) {
    // 공격 로직
}

가독성과 안전성
- 숫자의 모호함 -> 0dl '대기'인지, 1이 '공격'인지 기억하기 어려움
- 값의 오염 -> 상태 변수에 정의되지 않은 이상한 숫자가 들어가는 것을 막기 힘듦

if (state ==3) 보다 if (state == EState::ATTACK)이 더 가독성이 좋음

enum class EMonsterType {
    ORC,
    SLIME
};

// 사용 시 반드시 범위를 명시해야 함 (EMonsterType::)
EMonsterType myTarget = EMonsterType::ORC;

enum class도 있는데, 일반 enum과 다르게 이름이 겹치지않게 사용가능.

enum EState {
    IDLE,    // 0
    WALK,    // 1
    RUN,     // 2
    ATTACK   // 3
    END      // 4
};

std::string EStateName[EState::END] = { "IDLE",
										"WALK"
                                        "RUN"
                                        "ATTACK" };

처럼 추가해도 END의 숫자가 늘어나기 때문에 전체 요소의 개수를 자동으로 계산하기 위한 장치

Q.string EStateName처럼 해두는 이유가 뭔가요

enum class EStatType {
    MaxHP,
    MaxMP,
    Attack,
    Defense,
    Speed,
    Count 
};

class Character {
public:
    // 스탯을 배열 하나에 다 담아버림
    int Stats[(int)EStatType::Count];

    // 특정 스탯을 수정하는 함수 (하나의 함수로 모든 스탯 처리 가능)
    void UpgradeStat(EStateType type, int amount) {
        Stats[(int)type] += amount;
    }
};
  1. 하나의 함수로 모든 스탯 처리 가능
for (int i = 0; i < (int)EStatType::Count; ++i) {
    // "공격력 : 50" 이런 식으로 자동 출력
    RenderText(StatNames[i], Player->Stats[i]);
}
  1. 나중에 스탯 같은걸 출력할때 데이터가 늘어나도 출력 코드는 변하지 않는 개사기 코드 탄생함

Q.Enum과 Struct는 비슷한 것 같은데요?

비슷해보이지만 무엇을 담고있는지 차이가 있음.
일단 메모리 차이는
Enum(열거형) = 정수 하나만큼의 공간만 차지함 (보통 4바이트)
Struct(구조체) = 내부에 포함된 모든 변수의 크기를 합친만큼 차지함

struct Player {
    // 모든 스탯을 배열 하나에 담음
    int Stats[IntStatTypes::COUNT]; 

    // 사용법: 숫자가 아니라 '이름'으로 접근
    void TakeDamage(int damage) {
        Stats[IntStatTypes::TAKEN_DAMAGE] += damage;
        std::cout << IntStatNames[IntStatTypes::TAKEN_DAMAGE] << "이 누적되었습니다." << std::endl;
    }
};

이렇게 열거형과 구조체를 같이 써주는 방식이 많이 쓰임





싱글톤

Overview

"세상에 단 하나만 존재해야한다." 이게 싱글톤임.

Q.어떻게 막고 구현하나요?

  1. private 생성자 : 외부에서 new Manager()Manager m 처럼 직접 객체를 만들지 못하게 막는다.

  2. static 인스턴스 : 메모리의 정적 영역에 단 하나의 객체 주소를 보관

  3. GetInstance() 함수 : 외부에서 이 객체를 쓰고 싶을 때 오직 이 함수를 통해서만 허락된 인스터스를 받아가게 한다.

class SoundManager {
private:
    // 1. 생성자를 숨김 (외부에서 생성 불가)
    SoundManager() {} 
    
    // 복사 생성자와 대입 연산자도 막아야 완벽함
    SoundManager(const SoundManager& ref) = delete;
    SoundManager& operator=(const SoundManager& ref) = delete;

    static SoundManager* instance;

public:
    // 3. 오직 이 함수로만 접근 가능
    static SoundManager* GetInstance() {
        if (instance == nullptr) {
            instance = new SoundManager();
        }
        return instance;
    }

    void PlayBGM() { /* 배경음 재생 로직 */ }
};

// 2. 실제 메모리 할당 (정적 영역)
SoundManager* SoundManager::instance = nullptr;

0개의 댓글