코딩 학습/C와 C++

C++ 기초 - 포션 공방 만들기 과제

이개 2026. 3. 23. 19:44

4번 과제 구현하며 정리한 점을 적는다.

 

map에 원소 넣는 방법 3가지

 

 

std::map<std::string, int> m;

// [] 연산자 - 키가 없으면 추가, 있으면 덮어쓰기
m["sword"] = 100;
m["sword"] = 999; // 덮어씀

// insert - 키가 이미 있으면 무시 (덮어쓰기 안 함!)
m.insert({"sword", 999}); // sword 이미 있으면 그냥 무시
m.insert(std::make_pair("bow", 300)); // 구식 방법

// emplace - insert랑 동작 같은데 성능이 더 좋음
m.emplace("sword", 999); // sword 이미 있으면 그냥 무시



find 함수 쓰는법

PotionRecipe searchRecipeByName(std::string name) {
    auto it = std::find_if(recipes.begin(), recipes.end(),
        [&name](const PotionRecipe& recipe) {
            return recipe.potionName.find(name) != std::string::npos;
        }
    );

    if (it != recipes.end()) {
        return *it;
    }
    return PotionRecipe();
}

 

  • find는 find는 못 찾으면 npos를 반환
    • npos = "없음" 을 나타내는 특수값
  • 언리얼 FString은 Contains 바로 쓸 수 있다
    •  recipe.potionName.Contains(name);

 

cin 함수들

cin.fail

// 1. 입력이 실패했는지 확인
if (std::cin.fail()) {
    // int 받으려는데 "abc" 같은 문자 입력하면 fail() = true
// 3. cin 에러 플래그 초기화
std::cin.clear();
// fail() 상태를 정상으로 되돌림
// 안 하면 cin이 먹통 상태로 계속 있음
// 4. 입력 버퍼 비우기
std::cin.ignore(10000, '\n');
// 잘못 입력한 "abc\n" 이 버퍼에 남아있음
// '\n' 나올 때까지 최대 10000글자 버림
// 안 하면 다음 cin에서 쓰레기값 또 읽어버림

cin.fail() → 입력 실패 감지

cin.clear() → 에러 플래그 초기화

cin.ignore(n, '\n') → 버퍼 쓰레기값 제거

 

clear() 랑 ignore() 는 항상 세트

 

 

람다

[](const PotionRecipe& recipe) {
    return recipe.potionName == "Health Potion";
}

[]                    // 외부 변수 사용 안 함
[&searchName]         // searchName을 참조로 가져옴
[searchName]          // searchName을 복사로 가져옴
[&]                   // 외부 변수 전부 참조로 가져옴
[=]                   // 외부 변수 전부 복사로 가져옴

 

자바 람다는 외부 변수를 자동으로 캡처하는데 C++ 람다는 뭘 가져올지 직접 명시해야함.

 

 

pragma warning

#pragma warning(default : 4715)
// 4715 = 모든 경로에서 return 없을 때 경고

 

 

반환값에서의 const와 & 참조

const std::vector<PotionRecipe>& result = getAllRecipes();
result.push_back(recipe); // ❌ 에러! const라 수정 불가
result[0].potionName;     // ✅ 읽기만 가능
// & 없으면 - 벡터 전체를 복사해서 반환 (느림 😢)
std::vector<PotionRecipe> getAllRecipes()

// & 있으면 - 원본 벡터 참조만 반환 (빠름 ✅)
const std::vector<PotionRecipe>& getAllRecipes()

 

 

static, constexpr

const int a = 3;        // 런타임에 값 확정
constexpr int b = 3;    // 컴파일 타임에 값 확정 (더 빠름!)

// constexpr은 const보다 더 강력한 버전이야
// 컴파일할 때 이미 3으로 박혀버림

static constexpr int MAX_STOCK = 3;

class Shop {
public:
    static constexpr int MAX_STOCK = 3;
};

// 객체 없이 클래스로 바로 접근 가능
Shop::MAX_STOCK; // ✅
Shop shop;
shop.MAX_STOCK;  // ✅ 이것도 되긴 함

// 자바로 치면
// static final int MAX_STOCK = 3; 이랑 똑같아!

 

const vs constexpr 차이

int userInput;
std::cin >> userInput;

const int a = userInput;      // ✅ 런타임 값도 OK
constexpr int b = userInput;  // ❌ 컴파일 타임에 모르는 값 안 됨!
constexpr int c = 3;          // ✅ 컴파일 타임에 아는 값만 OK

 

 

웹개발에 비유를 해보자면,

AlchemyWorkShop은 URL대신 콘솔 입출력을 받는 컨트롤러단, RecipeManager나 StockManager는 컨트롤러에서 호출하는 서비스들이 저장 데이터를 스스로 가지고 있는 버전이고 PotionRecipes는 DTO라고 볼 수 있겠다.

 

반환 타입이 클래스일 때 null 반환을 못하니, 빈 객체를 반환하는 식으로 하거나 반환값을 포인터로 해서 nullptr을 반환한다.