C ++如何使用类和函数将我的代码转换为OOP? [英] C++ How to translate my code to OOP with classes and functions?

查看:67
本文介绍了C ++如何使用类和函数将我的代码转换为OOP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆