代码之家  ›  专栏  ›  技术社区  ›  Ramin Amiri

在条件语句中是否有声明对象的方法?

  •  6
  • Ramin Amiri  · 技术社区  · 5 年前

    flowchart

    我很难理解如何根据用户的选择正确地创建对象。

    在程序中,我问用户他们想成为什么样的人——骑士或巫师。我接受输入“1”或“2”来表示骑士和巫师。

    我做了一个转换声明,在案例1中,我声明了一个对象骑士,而对于巫师也是如此。

    我需要在switch语句之外使用这些对象,但我不能。我试图通过设置“player player”;来创建“default”对象,但由于player类具有纯虚拟函数,所以我也不能这样做。

    我如何有效地做到这一点?

    这就是我目前为止所拥有的:

    int main()
    {
    std::string plyrName;
    int input;
    bool foo = false;
    
    std::cout << "What is your name?\n";
    std::cin >> plyrName;
    std::cin.ignore(1000, '\n');
    
    std::cout << "\nWelcome, " << plyrName << ". What class would you like to be?\n";
    std::cout << "1. Knight.\n2. Wizard.\n";
    std::cin >> input;
    
    while (input != 1 && input != 2)
    {
        if (foo == true)
            std::cout << "Please enter 1 for Knight and 2 for Wizard.\n";
        if (!(std::cin >> input))
        {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "\n";
            std::cout << "Only integers are allowed.\n";
        }
        else
            std::cout << "\n";
        foo = true;
    }
    
    switch (input)
    {
    case 1:
    {
        Wizard player;
        break;
    }
    case 2:
    {
        Knight player;
        break;
    }
    }
    
    
    std::cout << "\nHere is your player information summary.\n";
    std::cout << player.classType();
    
    system("pause");
    return 0;
    }
    

    在创建之后,我需要访问player对象,因为我想输出给用户他们选择的类。Knight和巫师类都有一个函数来输出这个。

    编辑: 我有一个后续问题。在图中,Knight&wizard有一个静态变量“特殊攻击名称”。如何在主函数中访问这个变量?使用唯一指针的解决方案意味着指针将指向基类播放器,因此不允许访问派生类成员,如静态变量“特殊攻击名称”。我的设计有缺陷吗?

    3 回复  |  直到 5 年前
        1
  •  6
  •   Kunal Puri    5 年前

    在您的例子中,因为您想要完成多态性,所以应该使用指针和引用。为什么?我强烈推荐这个漂亮的答案。 Why doesn't polymorphism work without pointers/references?

    所以,你应该找一个原始指针,比如 Player * ?

    在几乎所有的场景中,您都不应该使用原始指针,尤其是当它指向动态内存时。仅仅因为任何编程错误或异常都可能导致 delete 被跳过了。

    因此,我强烈建议您使用C++ 11中引入的智能指针。 unique_ptr shared_ptr 遵循RAII模式,保证去初始化。

    以下是使用 尤尼奎 以你为例。

    #include <memory>
    
    using PlayerPtr = std::unique_ptr<Player>;
    using KnightPtr = std::unique_ptr<Knight>;
    using WizardPtr = std::unique_ptr<Wizard>;
    
    int main()
    {
        ...
        PlayerPtr playerPtr = nullptr;
    
        switch (input) {
            case 1: {
                 playerPtr = KnightPtr(new Knight);
            }
            break;
    
            case 2: {
                 playerPtr = WizardPtr(new Wizard);
            }
            break;
        }
    
        // use playerPtr outside.
    }
    

    编辑:

    正如正确指出的那样 HTNW 你必须去 std::make_unique 而不是使用 new . 但是请记住,这是C++ 14的概念。必须有编译器支持。

        2
  •  1
  •   Spinkoo    5 年前

    如果在switch case作用域内创建变量,那么一旦离开该作用域并将其引到ub,它就会被删除,因此将其声明为指针,这样它可以比条件语句更持久,即:在将其声明为基类指针之前,将其声明为条件语句内指向的位置

    #include<memory>
    int main()
    {
    std::string plyrName;
    int input;
    bool foo = false;
    //create your player ptr
    std::unique_ptr<Game_Object> player;
    std::cout << "What is your name?\n";
    std::cin >> plyrName;
    std::cin.ignore(1000, '\n');
    
    std::cout << "\nWelcome, " << plyrName << ". What class would you like to be?\n";
    std::cout << "1. Knight.\n2. Wizard.\n";
    std::cin >> input;
    
    while (input != 1 && input != 2)
    {
        if (foo == true)
            std::cout << "Please enter 1 for Knight and 2 for Wizard.\n";
        if (!(std::cin >> input))
        {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "\n";
            std::cout << "Only integers are allowed.\n";
        }
        else
            std::cout << "\n";
        foo = true;
    }
    
    switch (input)
    {
    case 1:
    {   // initialize it  and it would work perfectly as you intend
        player = std::make_unique<WIZARD>();
        break;
    }
    case 2:
    {   //****
        player = std::make_unique<KNIGHT>();
        break;
    }
    }
    
    
    std::cout << "\nHere is your player information summary.\n";
    std::cout << player->classType();
    
    system("pause");
    return 0;
    }
    
        3
  •  0
  •   gsamaras    5 年前

    如果我错了,有人会纠正我,但是对象只在它们被创建的范围内有效,所以一旦您退出switch语句,这些对象就不能再访问了。

    您应该在switch语句之外声明一个游戏对象类对象,然后创建向导或骑士(因为这两个类都继承了游戏对象)。