25.01.03 (금)

2025. 1. 3. 21:08·내배캠/TIL

 

클래스 상속관계에서 구성관계로 변경

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>

using namespace std; // namespace std 사용

class Book
{
public:
    string title;
    string author;

    Book(const string& title, const string& author)
        : title(title), author(author) {
    }
};

class BorrowManager
{
protected:
    unordered_map<string, int> stock;

private:
    int quantity;

public:
    // 재고 개수를 3개로 초기화
    BorrowManager() : quantity(3) {}

    // 책의 이름과 저자, 재고를 리스트에 저장 메서드
    void initializeStock(Book book)
    {
        stock[book.title + ":" + book.author] = quantity;
    }

    // 책 대여 가능 여부 출력 메서드
    void displayStock(const string& TitleAndAuthor)
    {
        auto it = stock.find(TitleAndAuthor);
        if (it != stock.end())
        {
            cout << it->second << "개의 재고가 있으므로 대여가 가능합니다.\n" << endl;
        }
        else
        {
            cout << "재고가 없으므로 대여가 불가능합니다." << endl;
        }
    }

    // 책 대여 메서드
    void borrowBook(const string& TitleAndAuthor)
    {
        auto it = stock.find(TitleAndAuthor);
        size_t pos = TitleAndAuthor.find(":");
        string author = TitleAndAuthor.substr(pos + 1);
        string title = TitleAndAuthor.substr(0, pos);

        if (it != stock.end())
        {
            if (it->second > 0)
            {
                it->second--;
                cout << endl << author << " 저자의 " << title << " 책을 대여 처리 하였습니다. 현재 재고는 " << it->second << "권 입니다." << endl;
            }
            else
            {
                cout << endl << title << " 책의 재고가 없습니다. 재고를 확인하세요." << endl;
            }
        }
        else
        {
            cout << endl << title << " 책이 목록에 존재하지 않아 대여 처리할 수 없습니다." << endl;
        }
    }

    // 책 반납 메서드
    void returnBook(const string& TitleAndAuthor)
    {
        auto it = stock.find(TitleAndAuthor);
        size_t pos = TitleAndAuthor.find(":");
        string author = TitleAndAuthor.substr(pos + 1);
        string title = TitleAndAuthor.substr(0, pos);

        if (it != stock.end())
        {
            if (it->second < 3)
            {
                it->second++;
                cout << endl << author << " 저자의 " << title << " 책이 반납 되었습니다. 현재 재고는 " << it->second << "권 입니다." << endl;
            }
            else
            {
                cout << endl << author << " 저자의 " << title << " 책의 재고가 3권으로 이미 가득 차 있습니다. 반납 처리할 수 없습니다." << endl;
            }
        }
        else
        {
            cout << title << "\n 책이 목록에 존재하지 않아 반납할 수 없습니다." << endl;
        }
    }
};

class BookManager 
{
private:
    vector<Book> books; // 책 목록 저장
    BorrowManager borrowManager; // 책 대여 클래스 선언
public:
    // 책 추가 메서드
    void addBook(const string& title, const string& author)
    {
        books.push_back(Book(title, author));
        borrowManager.initializeStock(Book(title, author));
        cout << "\n책이 추가되었습니다: " << title << " by " << author << endl;
    }

    // 모든 책 출력 메서드
    void displayAllBooks() const
    {
        if (books.empty())
        {
            cout << "현재 등록된 책이 없습니다." << endl;
            return;
        }

        cout << "현재 도서 목록:" << endl;
        for (size_t i = 0; i < books.size(); i++)
        {
            cout << "- " << books[i].title << " by " << books[i].author << endl;
        }
    }

    // 책의 제목이나 저자로 검색 메서드
    // 책이 있는지 검색해 출력하고 해당 책의 재고를 출력합니다.
    void searchByTitleOrAuthor(const string& search)
    {
        for (Book book : books)
        {
            if (book.title == search || book.author == search)
            {
                cout << endl << book.author << " 저자의 " << book.title << " 책이 있습니다." << endl;
                borrowManager.displayStock(book.title + ":" + book.author);
                return;
            }
        }
        cout << search << " 책이 없습니다." << endl;
    }

    // 책의 제목이나 저자를 재고 관리 key로 반환 메서드
    string MakeSearchKey(const string& search)
    {
        for (Book book : books)
        {
            if (book.title == search || book.author == search)
            {
                return book.title + ":" + book.author;
            }
        }
        return "";
    }

    // 대여관리 클래스의 책 대여 메서드 호출
    // BorrowManager 클래스의 기능을 연결합니다.
    void borrowBook(const string& key)
    {
        string searchKey = MakeSearchKey(key);
        if (!searchKey.empty())
        {
            borrowManager.borrowBook(searchKey);
        }
    }

    // 대여관리 클래스의 책 반납 메서드 호출
    // BorrowManager 클래스의 기능을 연결합니다.
    void returnBook(const string& key)
    {
        string searchKey = MakeSearchKey(key);
        if (!searchKey.empty())
        {
            borrowManager.returnBook(searchKey);
        }
    }
};


int main() {
    BookManager manager;

    // 도서관 관리 프로그램의 기본 메뉴를 반복적으로 출력하여 사용자 입력을 처리합니다.
    // 프로그램 종료를 선택하기 전까지 계속 동작합니다.
    while (true) {
        cout << "\n도서관 관리 프로그램" << endl;
        cout << "1. 책 추가" << endl; // 책 정보를 입력받아 책 목록에 추가
        cout << "2. 모든 책 출력" << endl; // 현재 책 목록에 있는 모든 책 출력
        cout << "3. 책 검색" << endl;
        cout << "4. 책 대여" << endl;
        cout << "5. 책 반납" << endl;
        cout << "6. 종료" << endl; // 프로그램 종료
        cout << "선택: ";

        int choice; // 사용자의 메뉴 선택을 저장

        while (true)
        {
            cin >> choice;

            if (cin.fail() || !(1 <= choice && choice <= 6))
            {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                cout << "잘못된 입력입니다. 다시 입력하세요." << endl;
                continue;
            }
            break;
        }

        if (choice == 1)
        {
            // 1번 선택: 책 추가
            // 사용자로부터 책 제목과 저자명을 입력받아 BookManager에 추가합니다.
            string title, author;
            cout << "책 제목: ";
            cin.ignore(); // 이전 입력의 잔여 버퍼를 제거
            getline(cin, title); // 제목 입력 (공백 포함)
            cout << "책 저자: ";
            getline(cin, author); // 저자명 입력 (공백 포함)
            manager.addBook(title, author); // 입력받은 책 정보를 추가
        }
        else if (choice == 2)
        {
            // 2번 선택: 모든 책 출력
            // 현재 BookManager에 저장된 책 목록을 출력합니다.
            manager.displayAllBooks();
        }
        else if (choice == 3)
        {
            // 3번 선택: 책 검색 및 대여 가능 여부 출력
            // 입력한 책의 대여 가능 여부와 현재 재고를 확인해 출력합니다.
            cout << "\n책의 제목이나 저자로 검색하세요: ";

            string search;
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            getline(cin, search);
            manager.searchByTitleOrAuthor(search);
        }
        else if (choice == 4)
        {
            // 4번 선택: 책 대여
            // 사용자가 입력한 책을 대여 처리하고, 현재 재고를 출력합니다.

            cout << "\n대여하실 책의 제목이나 저자를 입력하세요: ";

            string input;
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            getline(cin, input);
            manager.borrowBook(input);
        }
        else if (choice == 5)
        {
            // 5번 선택: 책 반납
            // 사용자가 입력한 책을 반납 처리하고, 현재 재고를 출력합니다.
            cout << "\n반납하실 책의 제목이나 저자를 입력하세요: ";

            string input;
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            getline(cin, input);
            manager.returnBook(input);
        }
        else if (choice == 6)
        {
            // 6번 선택: 종료
            // 프로그램을 종료하고 사용자에게 메시지를 출력합니다.
            cout << "프로그램을 종료합니다." << endl;
            break; // while 루프 종료
        }
        else
        {
            // 잘못된 입력 처리
            // 메뉴에 없는 번호를 입력했을 경우 경고 메시지를 출력합니다.
            cout << "잘못된 입력입니다. 다시 시도하세요." << endl;
        }
    }

    return 0; // 프로그램 정상 종료
}

어제 책 관리 클래스를 만들었었는데, BookManager 클래스가 BorrowManager클래스를 상속받아 대여에 관한 기능들을 사용하도록 했었다.

근데 이렇게 했을 때, BookManager의 역할과 책임들이 더 커지게 된다고 생각이들어 BookManager와 BorrowManager를 구성관계로 수정하였다.

 

수정하고 보니 사용자가 BookManager 클래스에서 BorrowManager의 책 대여 기능과 반납 기능을 사용하기 위해 함수를 또 만들었어야되는데, 코드가 더 길어져서 좋은건지 잘 모르겠다.. 사용자 입장에선 BookManager클래스 하나로 BorrowManager의 기능을 사용할 수 있어서 편리하긴 한 것 같고...

 

아직까지 좋은 설계에 대한 감이 잘 잡히지 않는다. GPT로 게임 관련한 클래스 설계를 공부할 수 있도록 해서 많은 연습이 필요할 것 같다.

 

 

 

비트 연산자

https://dong-grae.tistory.com/89

 

대칭되는 문자열 만들기

주어진 food 배열을 가지고 규칙에 맞게 왼쪽과 오른쪽이 대칭되는 문자열을 만들어 반환하는 문제였다. *초기 작성 코드#include #include #include using namespace std;string solution(vector food) { string answer = ""

dong-grae.tistory.com

비트 연산자 ">>" 에 대해 추가적으로 공부해서 정리를 해봤다.

연산자도 연산자인데 아직 비트의 개념이 잘 안잡혀 있는 듯해서 날 잡아서 비트와 비트연산자에 대해 파야될 것 같다.

'내배캠 > TIL' 카테고리의 다른 글

25.01.07 (화)  (1) 2025.01.07
25.01.06 (월)  (0) 2025.01.06
25.01.02 (목)  (1) 2025.01.02
24.12.31 (화)  (0) 2024.12.31
24.12.30 (월)  (0) 2024.12.30
'내배캠/TIL' 카테고리의 다른 글
  • 25.01.07 (화)
  • 25.01.06 (월)
  • 25.01.02 (목)
  • 24.12.31 (화)
동그래님
동그래님
  • 동그래님
    개발자 동그래
    동그래님
  • 전체
    오늘
    어제
    • 분류 전체보기 (210)
      • 공부 (51)
        • Code Cata (50)
      • 내배캠 (151)
        • TIL (50)
        • C++ (37)
        • Unreal Engine (48)
        • GAS(Gameplay Ability System.. (16)
      • Project (7)
        • Gunfire Paragon (5)
        • Arena Fighters (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    동그래님
    25.01.03 (금)
    상단으로

    티스토리툴바