有没有办法在条件语句中声明对象?

时间:2019-01-28 14:48:10

标签: c++ object if-statement

flowchart

我在弄清楚如何根据用户的选择正确创建对象时遇到了麻烦。

在程序中,我问用户他们想成为哪个类的骑士或向导。我输入“ 1”或“ 2”代表骑士和巫师。

我做了一个switch语句,在第一种情况下,我声明了一个对象Knight,对于Wizard来说也是一样。

我需要在switch语句之外使用这些对象,但是我不能。我试图通过制作“播放器”来制作“默认”对象;但是由于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;
}

创建之后,我需要访问播放器对象,因为我想向用户输出他们选择的类。 Knight和Wizard类都具有输出此函数的功能。

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

3 个答案:

答案 0 :(得分:6)

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

那么,您应该使用Player *之类的原始指针吗?

在几乎所有情况下,绝对不要使用原始指针,尤其是当它指向动态内存时。仅仅是因为任何编程错误或异常都可能导致delete被跳过。

因此,我强烈建议您使用C ++ 11中引入的智能指针,例如unique_ptrshared_ptr,它们遵循RAII模式并保证反初始化。

这里是您使用unique_ptr的示例。

#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的概念。您必须对此具有编译器支持。

答案 1 :(得分:1)

如果在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;
}

答案 2 :(得分:0)

如果我错了,请有人纠正我,但是对象仅在它们创建的范围内有效,因此一旦您退出该switch语句,这些对象将无法再访问。

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