C++ 4번 과제: 연금술 공방 관리
- 해당 과제에선 기본적으로 제공된 코드에 과제 목표에 해당하는 메서드를 추가하는 형식이었기에, 그렇게 긴 코드를 작성할 필요는 없었다.
레시피 이름으로 포션 검색
PotionRecipe searchRecipeByName(const std::string& name) const
{
auto it = std::find(recipes.begin(), recipes.end(), name);
if (it != recipes.end())
{
PotionRecipe foundPotion = *it;
return foundPotion;
}
else
{
return PotionRecipe("", {});
}
}
else if (choice == 3)
{
std::string name;
std::cout << "Search for potion name: ";
std::cin.ignore(10000, '\n');
std::getline(std::cin, name);
PotionRecipe foundPotion = myWorkshop.searchRecipeByName(name);
if (foundPotion.potionName != "")
{
std::cout << "Found the Potion!" << std::endl;
foundPotion.displayPotionInfo();
}
else
{
std::cout << "Could not find a potion matching the name." << std::endl;
}
}
std::cin ignore (10000, '\n') 을 통해 인풋을 확실히 지우고 새로 받는 것.
const가 붙는 위치에 주의 - 읽기만 하는 레퍼런스, 함수 등에는 const를 항상 붙히는 습관을 들이자.
const PotionRecipe* foundRecipe 같이 const 객체를 가리키는 포인터는 const 함수만 이용 가능하다는 것도 주의.
- 사실
std::find() 안에는 string 을 비교하는 기능이 없다.
bool operator==(const std::string& otherName) const
{
return potionName == otherName;
}
- 비교를 위헤
class PotionRecipe 안에 같음을 비교하는 == 연산자에 override 할 수 있는 비교함수를 새로 작성했다. 이러면 find 안에서 string 변수를 비교할 수 있게 된다.
- 과제 사양대로
PotionRecipe 클래스를 반환하는 식으로 함수를 작성했지만, 사실 검색만 하는 것이므로 포인터나 레퍼런스를 반환하는 방식도 괜찮았을 듯하다. 포인터의 경우 찾지 못했을 경우 nullptr을 반환하는 식으로 해도 괜찮겠지만 이 경우 레시피 그 자체를 반환하므로 빈 레시피 생성자 PotionRecipe("",{}) 를 사용했다.
레시피 재료로 포션 검색
std::vector<PotionRecipe> searchRecipeByIngredient(const std::string& ingredient) const
{
std::vector<PotionRecipe> foundRecipes;
for (const PotionRecipe& recipe : recipes)
{
for (const std::string& searchIngredient : recipe.ingredients)
{
if (searchIngredient == ingredient)
{
foundRecipes.push_back(recipe);
break;
}
}
}
return foundRecipes;
}
else if (choice == 4)
{
std::string name;
std::cout << "Search for ingredient name: ";
std::cin.ignore(10000, '\n');
std::getline(std::cin, name);
std::vector <PotionRecipe> foundPotions = myWorkshop.searchRecipeByIngredient(name);
if (foundPotions.size() != 0)
{
for (const PotionRecipe& i : foundPotions)
{
i.displayPotionInfo();
}
}
else
{
std::cout << "Could not find a potion with that ingredient." << std::endl;
}
}
- 이 경우 복수의 레시피를 반환해야 하기 때문에,
range-for 문을 활용했다.
for(const 원소클래스명& 변수명: 벡터명)
const+클래스명+& : const로 복사를 방지하고, & 로 매번매번 해당 요소 대입/복사 안하고 주소만 가져오겠다는 의미
- 레시피들을 담은 벡터에서 레시피별로 for문을 돌리고, 레시피들에서 재료들을 담은 벡터에서 재료별로 if문을 돌리는 형식.
break; 는 가장 근처에 있는 반복문을 탈출하는 기능. 이 경우 같은 재료가 복수로 담겨 있는 레시피들도 한번씩만 등록해 주기 위해 넣었다.