C ++如何使用类和函数将我的代码转换为OOP? [英] C++ How to translate my code to OOP with classes and functions?
问题描述
我对OOP编程很陌生,想知道如何使我的代码更整洁.该程序可以运行,但是我不知道如何为流派,玩家输入等设置不同的类.
我尝试为带有.h和.cpp文件的流派创建一个类,但是我对如何使代码更整洁还不了解,因为所有内容都在以下位置创建:int main(){} >
bookPicker.cpp
int main()
{
//Declaring a user account
std::string name, lastName;
//Genre's
std::string ice, fire, earth, wind;
ice = "Ice", fire = "Fire", earth = "Earth", wind = "Wind";
//Titles
int a, b, c, d;
//Recommendation
std::string r;
r = "Type yess if this is the genre of your choice\n";
std::string iceS[4] = { "The Ice Gauntlet", "The Formal Ice Queen", "Frozen in Time", "Frost Lake" };
std::string fireS[4] = { "The Fire Gauntlet", "The Formal Fire Queen", "Hot Air", "Fire Lake" };
std::string earthS[4] = { "The Earth Gauntlet", "The Formal Earth Queen", "Stuck in Time", "The Swamp" };
std::string windS[4] = { "The Wind Gauntlet", "The Formal Wind Queen", "Blown in Time", "Wind Lake" };
//Welcome
std::string w, wU;
w = "Welcome ";
wU = " to The Four Elemets Book Store!\n";
//Creating user account
std::cout << "Please enter your name" << std::endl;
std::cin >> name;
std::cout << "Please enter your lastname" << std::endl;
std::cin >> lastName;
std::string userAccount = name + lastName;
//Ask for input
std::cout << w << userAccount << std::endl;
std::cout << "What kind of genre do you like to read? \n" << std::endl;
std::cout << ice << "\n" << fire << "\n" << earth << "\n" << wind << "\n" << std::endl;
std::cout << "Please pick your genre\n" << std::endl;
//create the choice string variable
std::string choice;
std::cin >> choice;
//if statement after the input
if (choice == ice) {
std::cout << r << std::endl;
std::cin >> a;
std::cout << "\n";
for (int i = 0; i < 4; i++) {
std::cout << iceS[i] << "\n";
}
} if (choice == fire) {
std::cout << r << std::endl;
std::cin >> b;
std::cout << "\n";
for (int y = 0; y < 4; y++) {
std::cout << fireS[y] << "\n";
}
} if (choice == earth) {
std::cout << r << std::endl;
std::cin >> c;
std::cout << "\n";
for (int x = 0; x < 4; x++) {
std::cout << earthS[x] << "\n";
}
} if (choice == wind) {
std::cout << r << std::endl;
std::cin >> d;
std::cout << "\n";
for (int o = 0; o < 4; o++) {
std::cout << windS[o] << "\n";
}
}
return 0;
}
由于示例程序现在已经存在,因此OOP并没有多少改进.当然,根据程序的发展方式,它可能会改变.如果我要上课,可能就是这样:
class account {
public:
std::string name;
std::string lastName;
std::string getFullName() {
return name + " " + lastName;
}
};
在这里,account
现在表示用户记录,并且getFullName
可以用于清晰打印其名称.您这样创建帐户:
//Declaring a user account
account userAcc;
您可以这样设置名称:
std::cout << "Please enter your name" << std::endl;
std::cin >> userAcc.name;
std::cout << "Please enter your lastname" << std::endl;
std::cin >> userAcc.lastName;
然后您以这种方式打印名称:
//Ask for input
std::cout << w << userAcc.getFullName() << std::endl;
当然,这不会改善任何状况,因为您反正只有一个用户.我认为重复的if
链中有很大的改进潜力,这些链约占您代码的一半.取而代之的是,我将利用您的四个元素以这种方式枚举事物的事实:
enum element {
ICE, FIRE, EARTH, WIND, NONE
};
std::vector<std::vector<std::string>> books = {
{"The Ice Gauntlet", "The Formal Ice Queen", "Frozen in Time", "Frost Lake" },
{ "The Fire Gauntlet", "The Formal Fire Queen", "Hot Air", "Fire Lake" },
{ "The Earth Gauntlet", "The Formal Earth Queen", "Stuck in Time", "The Swamp" },
{ "The Wind Gauntlet", "The Formal Wind Queen", "Blown in Time", "Wind Lake" }
};
现在我们有一个element
枚举,但稍后会进行更多说明.请注意,这些书现在是字符串向量的向量,这种结构很像表格.现在要找出用户想要的元素,我们可以像这样查询它:
//if statement after the input
element chosenElement = NONE;
if (choice == ice) chosenElement = ICE;
else if (choice == fire) chosenElement = FIRE;
else if (choice == earth) chosenElement = EARTH;
else if (choice == wind) chosenElement = WIND;
现在chosenElement
表示用户想要的元素,如果输入的内容无效,则分别表示NONE
.现在,您可以通过以下方式打印所有书籍:
if (chosenElement == NONE) {
std::cout << "Sorry, we don't have this genre." << std::endl;
}
else for (std::string i : books[chosenElement]) {
std::cout << i << std::endl;
}
这将替换您之前拥有的整个if
链. books[chosenElement]
代表类型中的所有书籍(因此books[ICE]
是所有冰书,依此类推),i
是相应的书籍,它们都以这种方式打印.
该程序也可以通过这种方式更轻松地扩展.假设您有一个新元素,只需将其值添加到NONE
之前的enum
定义中,将这行书添加到字符串向量的books
向量中,然后添加一个else if (choice...
检查对于新元素,您已经完成.无需复制/粘贴任何if
块.此外,您不再依赖于对每种类型的书籍数量进行硬编码.您可以只将第五本书添加到该类型中,这样就可以工作.由于基于范围的for
循环可以自行发现这一点,因此无需告诉它该类别中有多少本书.
此外,如果您只需要一个字符串并且不会修改它,我建议不要为其创建std::string
.代替这个:
std::string ice, fire, earth, wind;
ice = "Ice", fire = "Fire", earth = "Earth", wind = "Wind";
...
if (choice == ice)
我会这样做:
if (choice == "Ice")
之所以可行,是因为std::string
具有必要的重载,因此它知道当您将==
与这样的字符串文字一起使用时,您想进行字符串比较. std::string w, wU;
也是如此,我只是将它们取出,然后将字符串文字放在打印它们的位置.
I am quite new to OOP programming and would like to know how to get my code cleaner. The program works but I don't know how to make different classes for Genres, player input etc.
I tried creating a class for the Genres with a .h and .cpp file, but I still have not many knowledge on how to make my code cleaner, since everything is created in the: int main () {}
bookPicker.cpp
int main()
{
//Declaring a user account
std::string name, lastName;
//Genre's
std::string ice, fire, earth, wind;
ice = "Ice", fire = "Fire", earth = "Earth", wind = "Wind";
//Titles
int a, b, c, d;
//Recommendation
std::string r;
r = "Type yess if this is the genre of your choice\n";
std::string iceS[4] = { "The Ice Gauntlet", "The Formal Ice Queen", "Frozen in Time", "Frost Lake" };
std::string fireS[4] = { "The Fire Gauntlet", "The Formal Fire Queen", "Hot Air", "Fire Lake" };
std::string earthS[4] = { "The Earth Gauntlet", "The Formal Earth Queen", "Stuck in Time", "The Swamp" };
std::string windS[4] = { "The Wind Gauntlet", "The Formal Wind Queen", "Blown in Time", "Wind Lake" };
//Welcome
std::string w, wU;
w = "Welcome ";
wU = " to The Four Elemets Book Store!\n";
//Creating user account
std::cout << "Please enter your name" << std::endl;
std::cin >> name;
std::cout << "Please enter your lastname" << std::endl;
std::cin >> lastName;
std::string userAccount = name + lastName;
//Ask for input
std::cout << w << userAccount << std::endl;
std::cout << "What kind of genre do you like to read? \n" << std::endl;
std::cout << ice << "\n" << fire << "\n" << earth << "\n" << wind << "\n" << std::endl;
std::cout << "Please pick your genre\n" << std::endl;
//create the choice string variable
std::string choice;
std::cin >> choice;
//if statement after the input
if (choice == ice) {
std::cout << r << std::endl;
std::cin >> a;
std::cout << "\n";
for (int i = 0; i < 4; i++) {
std::cout << iceS[i] << "\n";
}
} if (choice == fire) {
std::cout << r << std::endl;
std::cin >> b;
std::cout << "\n";
for (int y = 0; y < 4; y++) {
std::cout << fireS[y] << "\n";
}
} if (choice == earth) {
std::cout << r << std::endl;
std::cin >> c;
std::cout << "\n";
for (int x = 0; x < 4; x++) {
std::cout << earthS[x] << "\n";
}
} if (choice == wind) {
std::cout << r << std::endl;
std::cin >> d;
std::cout << "\n";
for (int o = 0; o < 4; o++) {
std::cout << windS[o] << "\n";
}
}
return 0;
}
As the sample program is now, there's not much that OOP would improve. Of course, depending on how the program would evolve, that can change. If I would make a class, it would probably be this one:
class account {
public:
std::string name;
std::string lastName;
std::string getFullName() {
return name + " " + lastName;
}
};
Here, account
now represents a user record, and getFullName
can be used for a clean print of their name. You make the account like this:
//Declaring a user account
account userAcc;
You set the names like this:
std::cout << "Please enter your name" << std::endl;
std::cin >> userAcc.name;
std::cout << "Please enter your lastname" << std::endl;
std::cin >> userAcc.lastName;
And then you print the name this way:
//Ask for input
std::cout << w << userAcc.getFullName() << std::endl;
Of course, this isn't going to improve anything as-is because you only have one user anyway. I see bigger potential for improvement in the repetitive if
chain that make up about half of your code. Instead, I would leverage the fact that your four elements are used to enumerate things this way:
enum element {
ICE, FIRE, EARTH, WIND, NONE
};
std::vector<std::vector<std::string>> books = {
{"The Ice Gauntlet", "The Formal Ice Queen", "Frozen in Time", "Frost Lake" },
{ "The Fire Gauntlet", "The Formal Fire Queen", "Hot Air", "Fire Lake" },
{ "The Earth Gauntlet", "The Formal Earth Queen", "Stuck in Time", "The Swamp" },
{ "The Wind Gauntlet", "The Formal Wind Queen", "Blown in Time", "Wind Lake" }
};
Now we have an element
enumeration, but more on that later. Note how the books are now a vector of vector of strings, a structure that is a lot like a table. Now to find out which element the user wants, we can query it like this:
//if statement after the input
element chosenElement = NONE;
if (choice == ice) chosenElement = ICE;
else if (choice == fire) chosenElement = FIRE;
else if (choice == earth) chosenElement = EARTH;
else if (choice == wind) chosenElement = WIND;
Now chosenElement
represents the element that the user wanted, respectively NONE
if he entered something invalid. Now you can print all the books this way:
if (chosenElement == NONE) {
std::cout << "Sorry, we don't have this genre." << std::endl;
}
else for (std::string i : books[chosenElement]) {
std::cout << i << std::endl;
}
This replaces the entire if
chain that you had before. books[chosenElement]
represents all the books in a genre (so books[ICE]
is all the ice books, and so on) and i
is the respective book, and they all get printed this way.
The program can also be extended more easily that way. Suppose you have a new element, all you had to do is add its value to the enum
definition before the NONE
, add the row of books to the books
vector of vectors of strings, add an else if (choice...
check for the new element, and you're done. No need to copy/paste any if
block. Also, you're not dependent on hard-coding the amount of books per genre anymore. You could just add a fifth book to a genre and it would work like that. No need to tell it how many books there are in the genre because the range-based for
loop find that out on its own.
Also, if you're only going to need a string once and won't modify it, I would suggest not making an std::string
for it. Instead of this:
std::string ice, fire, earth, wind;
ice = "Ice", fire = "Fire", earth = "Earth", wind = "Wind";
...
if (choice == ice)
I would just do that:
if (choice == "Ice")
This works because std::string
has the necessary overloads so it knows you want to do string comparison when you use ==
with a string literal like that. The same goes for std::string w, wU;
, I'd just take them out and put the string literals where you print them.
这篇关于C ++如何使用类和函数将我的代码转换为OOP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!