전체 코드

🚀 1. 개요

C++11에서 람다 표현식(lambda expression)이 도입되면서 함수 객체(functor)를 더 간결하고 직관적으로 작성할 수 있게 되었습니다.
람다는 익명 함수로, 특정 코드 블록을 함수처럼 사용할 수 있습니다.

람다 기본 문법

[캡처 방식](매개변수) -> 반환 타입 { 함수 본문 };
  • [캡처]: 외부 변수를 람다 내부에서 어떻게 사용할지 결정
  • (매개변수): 함수처럼 전달할 수 있는 인자
  • -> 반환 타입: 반환 타입을 명시할 수 있으며, 생략하면 컴파일러가 자동 추론
  • { 함수 본문 }: 람다에서 실행할 코드

장점

  • 익명 함수를 만들 수 있어 코드가 간결해짐
  • 함수 객체(Functor)보다 직관적
  • 표준 라이브러리(STL)와의 궁합이 좋음
  • 캡처 기능으로 외부 변수 사용 가능

📂 2. 코드 분석

🎯 열거형(enum) 정의

enum class ItemType
{
    None,
    Armor,
    Weapon,
    Jewelry,
    Consumable
};
  • ItemTypeC++11의 enum class를 사용하여 타입 안전성을 보장
  • 각 아이템 유형을 구분하는 5가지 값 정의
enum class Rarity
{
    Common,
    Rare,
    Unique
};
  • 아이템의 희귀도를 나타내는 enum class
  • Common, Rare, Unique 값으로 구분

🎯 아이템 클래스(Item)

class Item
{
public:
    Item() { }
    Item(int itemId, Rarity rarity, ItemType type)
        : _itemId(itemId), _rarity(rarity), _type(type) { }
public:
    int _itemId = 0;
    Rarity _rarity = Rarity::Common;
    ItemType _type = ItemType::None;
};

Item 클래스

  • _itemId: 아이템의 고유 ID
  • _rarity: 아이템의 희귀도
  • _type: 아이템의 유형

생성자

  • 기본 생성자
  • 매개변수 생성자 → 초기화 리스트를 사용하여 멤버 변수를 초기화

🎯 벡터에 Item 저장

vector<Item> v;
v.push_back(Item(1, Rarity::Common, ItemType::Weapon));
v.push_back(Item(2, Rarity::Common, ItemType::Armor));
v.push_back(Item(3, Rarity::Rare, ItemType::Jewelry));
v.push_back(Item(4, Rarity::Unique, ItemType::Weapon));

std::vector를 사용하여 Item 저장

  • push_back을 이용해 4개의 Item 객체 추가
  • 아이템은 ID, 희귀도, 유형을 기반으로 생성됨

🎯 함수 객체(Functor)

struct IsUniqueItem
{
    bool operator()(Item& item)
    {
        return item._rarity == Rarity::Unique;
    }
};

함수 객체(Functor)

  • operator()를 오버로딩하여 함수처럼 사용 가능
  • Rarity::Unique인지 확인하는 역할
struct FindItemByItemId
{
    FindItemByItemId(int itemId) : _itemId(itemId) { }
    bool operator()(Item& item)
    {
        return item._itemId == _itemId;
    }
    int _itemId;
};

특정 itemId를 가진 아이템 찾기

  • _itemId를 기준으로 검색
struct FindItem
{
    FindItem(int itemId, Rarity rarity, ItemType type)
        : _itemId(itemId), _rarity(rarity), _type(type) { }
    bool operator()(Item& item)
    {
        return item._itemId == _itemId && item._rarity == _rarity && item._type == _type;
    }
    int _itemId;
    Rarity _rarity;
    ItemType _type;
};

여러 조건을 만족하는 아이템 찾기

  • itemId, rarity, type이 모두 일치해야 true 반환

🎯 람다 표현식 활용

auto isUniqueLambda = [](Item& item) { return item._rarity == Rarity::Unique; };

람다 표현식을 사용한 Rarity::Unique 확인

  • [ ]: 외부 변수를 캡처하지 않음
  • (Item& item): 매개변수
  • { return item._rarity == Rarity::Unique; }: 함수 본문
int itemId = 4;
Rarity rarity = Rarity::Unique;
ItemType type = ItemType::Weapon;
auto findByItem = [&itemId, &rarity, type](Item& item) {
    return item._itemId == itemId && item._rarity == rarity && item._type == type;
};

람다 표현식을 사용한 복합 조건 검색

  • [&itemId, &rarity, type]
    • &itemId, &rarity: 참조 캡처 (변경 가능)
    • type: 값 캡처 (읽기 전용)

🎯 람다와 std::find_if 활용

auto findIt = std::find_if(v.begin(), v.end(), FindItem(4, Rarity::Unique, ItemType::Weapon));
if (findIt != v.end())
{
    cout << "아이템 ID: " << findIt->_itemId << endl;
}

std::find_if로 조건을 만족하는 아이템 찾기

  • FindItem 함수 객체를 전달하여 특정 조건을 만족하는 Item 찾음

🎯 클래스 내부에서 람다 사용

class Knight
{
public:
    auto ResetHpJob()
    {
        auto f = [this]() { this->_hp = 200; };
        return f;
    }
public:
    int _hp = 100;
};

클래스 내부에서 this 캡처한 람다 사용

  • this 캡처로 멤버 변수 _hp를 변경 가능
Knight* k = new Knight();
auto job = k->ResetHpJob();
delete k; 
job();

문제 발생 가능성

  • delete k; 실행 후, job() 호출 시 이미 해제된 this를 참조
  • 해결 방법: 스마트 포인터(std::shared_ptr, std::unique_ptr) 사용

profile
李家네_공부방

0개의 댓글