[英]Passing struct to function without typing every member (C++ no pointers)
所以我認為更多沒有經驗的程序員會帶着這個問題四處游盪。 我可以像下面的代碼片段一樣成功地將結構傳遞給函數:
void printMonster(MonsterStats slime, MonsterStats spider, MonsterStats orc, MonsterStats ogre, MonsterStats dragon, int charLevel)
但是你可以想象,如果 struct MonsterStats 有 120 個成員,所有成員都需要傳遞給 printMonster 我的代碼將成為絕對的意大利面條!
所以問題是,如何在不將每個成員都輸入到函數參數中的情況下將這個結構傳遞到我的函數中?
有關此時我“應該”了解多少 C++ 的問題,我已經到達了learncpp.com 第 4 章綜合測驗。 我有點超出了任務的范圍,但我沒有做任何我現在不應該做的事情。
完整如下(工作但冗長):
#include <iostream>
struct MonsterStats
{
std::string type;
std::string name;
int health;
int level;
};
void printMonster(MonsterStats slime, MonsterStats spider, MonsterStats orc, MonsterStats ogre, MonsterStats dragon, int charLevel)
{
if(charLevel>=slime.level&&charLevel<spider.level)
std::cout << "This " << slime.type << " is named " << slime.name << " and has " << slime.health << " health.\n";
else if(charLevel>=spider.level&&charLevel<orc.level)
std::cout << "This " << spider.type << " is named " << spider.name << " and has " << spider.health << " health.\n";
else if(charLevel>=orc.level&&charLevel<ogre.level)
std::cout << "This " << orc.type << " is named " << orc.name << " and has " << orc.health << " health.\n";
else if(charLevel>=ogre.level&&charLevel<dragon.level)
std::cout << "This " << ogre.type << " is named " << ogre.name << " and has " << ogre.health << " health.\n";
else if(charLevel>=dragon.level)
std::cout << "This " << dragon.type << " is named " << dragon.name << " and has " << dragon.health << " health.\n";
}
int main()
{
using namespace std;
MonsterStats ogre{"Ogre","Grumble",345, 16}; //Type, Name, Health, Level
MonsterStats dragon{"Dragon","Spyro", 890, 21}; //Type, Name, Health, Level
MonsterStats orc{"Orc","Rakanishu", 165, 11}; //Type, Name, Health, Level
MonsterStats spider{"Giant Spider", "Arachnid", 80, 6}; //Type, Name, Health, Level
MonsterStats slime{"Slime", "Blurp", 35, 1}; //Type, Name, Health, Level
std::string getChoice="y";
int charLevel;
cout << "Please enter the level of your character to proceed to battle: ";
cin >> charLevel;
if(charLevel>0)
{
while(getChoice=="y")
{
printMonster(slime, spider, orc, ogre, dragon, charLevel);
cout << "Do you want to fight the monster? (y/n)";
cin >> getChoice;
if(getChoice=="y")
{
cout << "You destroyed the monster and gained an experience level!\n\n";
charLevel+=1;
}
else
cout << "You ran like Forest Gump and got out of the fight safely!\n\n";
}
}
else
cout << "Please create a character in order to play the game.";
return 0;
}
預先感謝您的回答:)
您傾向於稱之為“成員”(例如ogre
、 spider
等...)實際上是MonsterStats
結構的實例。 所以變數。
在 C++ 中,“成員”是結構中的變量或函數(例如name
、 health
、 level
等...)。
當然,在您的代碼片段中使用許多實例,並多次重新輸入相同的內容將是一場噩夢。 幸運的是,在第 5 章中您將看到循環,而在第 6 章中您將學習處理一組實例的數組和向量。
這看起來像:
#include <iostream>
#include <string>
#include <vector>
struct MonsterStats
{
...
};
...
int main()
{
using namespace std;
vector<MonsterStats> monsters {
{"Ogre","Grumble",345, 16},
{"Dragon","Spyro", 890, 21},
{"Orc","Rakanishu", 165, 11},
{"Giant Spider", "Arachnid", 80, 6},
{"Slime", "Blurp", 35, 1} };
...
printMonster(monsters, charlevel);
...
}
然后您將使用monsters[i]
訪問第i
個項目。
一旦您開始使用標准庫容器,您就可以使用標准庫進行排序和搜索:
void printMonster(std::vector<MonsterStats>& monsters, int charLevel)
{
MonsterStats mystats{"","",0,charLevel};
auto comp = [](const auto& i, const auto& j) {return i.level <= j.level; };
std::sort(monsters.begin(), monsters.end(), comp);
auto monster_iterator = std::lower_bound(monsters.begin(), monsters.end(), mystats, comp);
auto monster = *(monster_iterator - 1);
std::cout << "You have level " << charLevel << '\n';
std::cout << "This " << monster.type << " is named " << monster.name << " and has " << monster.health << " health.\n";
}
這是完整的程序:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
struct MonsterStats
{
std::string type;
std::string name;
int health;
int level;
};
void printMonster(std::vector<MonsterStats>& monsters, int charLevel)
{
MonsterStats mystats{"","",0,charLevel};
auto comp = [](const auto& i, const auto& j) {return i.level <= j.level; };
std::sort(monsters.begin(), monsters.end(), comp);
auto monster_iterator = std::lower_bound(monsters.begin(), monsters.end(), mystats, comp);
auto monster = *(monster_iterator - 1);
std::cout << "You have level " << charLevel << '\n';
std::cout << "This " << monster.type << " is named " << monster.name << " and has " << monster.health << " health.\n";
}
int main()
{
std::vector<MonsterStats> monsters{
{"Ogre","Grumble",345, 16}, //Type, Name, Health, Level
{"Dragon","Spyro", 890, 21}, //Type, Name, Health, Level
{"Orc","Rakanishu", 165, 11}, //Type, Name, Health, Level
{"Giant Spider", "Arachnid", 80, 6}, //Type, Name, Health, Level
{"Slime", "Blurp", 35, 1}}; //Type, Name, Health, Level
std::string getChoice = "y";
int charLevel;
std::cout << "Please enter the level of your character to proceed to battle: ";
std::cin >> charLevel;
if(charLevel>0)
{
while(getChoice == "y")
{
printMonster(monsters, charLevel);
std::cout << "Do you want to fight the monster? (y/n)";
std::cin >> getChoice;
if(getChoice == "y")
{
std::cout << "You destroyed the monster and gained an experience level!\n\n";
charLevel += 1;
}
else
std::cout << "You ran like Forest Gump and got out of the fight safely!\n\n";
}
}
else
std::cout << "Please create a character in order to play the game.";
return 0;
}
更干凈的程序可能是使用自定義比較器的多集(排序容器)。
比較器可以具有以下形式:
struct myComp {
bool operator()(const MonsterStats& i, const MonsterStats& j) {
return i.level < j.level;
}
};
並且多重集可以使用它:
using myMultiset = std::multiset<MonsterStats, myComp>;
然后,搜索可以更簡單,因為集合已經排序:
auto& monster = *--monsters.upper_bound(mystats);
打印可以使用<<
操作符:
std::ostream& operator<<(std::ostream& os, const MonsterStats& monster)
{
std::cout
<< "Monster has level: " << monster.level << '\n'
<< "This " << monster.type << " is named " << monster.name << " and has " << monster.health << " health.\n";
return os;
}
完整程序:
#include <iostream>
#include <string>
#include <set>
struct MonsterStats
{
std::string type;
std::string name;
int health;
int level;
};
struct myComp {
bool operator()(const MonsterStats& i, const MonsterStats& j) {
return i.level < j.level;
}
};
using myMultiset = std::multiset<MonsterStats, myComp>;
std::ostream& operator<<(std::ostream& os, const MonsterStats& monster)
{
std::cout
<< "Monster has level: " << monster.level << '\n'
<< "This " << monster.type << " is named " << monster.name << " and has " << monster.health << " health.\n";
return os;
}
int main()
{
myMultiset monsters{
{{"Ogre","Grumble",345, 16}, //Type, Name, Health, Level
{"Dragon","Spyro", 890, 21}, //Type, Name, Health, Level
{"Orc","Rakanishu", 165, 11}, //Type, Name, Health, Level
{"Giant Spider", "Arachnid", 80, 6}, //Type, Name, Health, Level
{"Slime", "Blurp", 35, 1}}}; //Type, Name, Health, Level
std::string getChoice = "y";
std::cout << "Please enter the level of your character to proceed to battle: ";
MonsterStats mystats{};
std::cin >> mystats.level;
if(mystats.level>0)
{
while(getChoice == "y")
{
auto& monster = *--monsters.upper_bound(mystats);
std::cout
<< "You have level " << mystats.level << '\n'
<< monster
<< "Do you want to fight the monster? (y/n)";
std::cin >> getChoice;
if(getChoice == "y")
{
std::cout << "You destroyed the monster and gained an experience level!\n\n";
++mystats.level;
}
else
std::cout << "You ran like Forest Gump and got out of the fight safely!\n\n";
}
}
else
std::cout << "Please create a character in order to play the game.";
return 0;
}
或者,如果您在結構中包含operator<
那么您可以進一步簡化:
#include <iostream>
#include <string>
#include <set>
struct MonsterStats
{
std::string type;
std::string name;
int health;
int level;
bool operator<(const MonsterStats& rhs) const {
return level < rhs.level;
}
};
using myMultiset = std::multiset<MonsterStats>;
std::ostream& operator<<(std::ostream& os, const MonsterStats& monster)
{
std::cout
<< "Monster has level: " << monster.level << '\n'
<< "This " << monster.type << " is named " << monster.name << " and has " << monster.health << " health.\n";
return os;
}
int main()
{
myMultiset monsters{
{{"Ogre","Grumble",345, 16}, //Type, Name, Health, Level
{"Dragon","Spyro", 890, 21}, //Type, Name, Health, Level
{"Orc","Rakanishu", 165, 11}, //Type, Name, Health, Level
{"Giant Spider", "Arachnid", 80, 6}, //Type, Name, Health, Level
{"Slime", "Blurp", 35, 1}}}; //Type, Name, Health, Level
std::string getChoice = "y";
std::cout << "Please enter the level of your character to proceed to battle: ";
MonsterStats mystats{};
std::cin >> mystats.level;
if(mystats.level>0)
{
while(getChoice == "y")
{
auto& monster = *--monsters.upper_bound(mystats);
std::cout
<< "You have level " << mystats.level << '\n'
<< monster
<< "Do you want to fight the monster? (y/n)";
std::cin >> getChoice;
if(getChoice == "y")
{
std::cout << "You destroyed the monster and gained an experience level!\n\n";
++mystats.level;
}
else
std::cout << "You ran like Forest Gump and got out of the fight safely!\n\n";
}
}
else
std::cout << "Please create a character in order to play the game.";
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.