如何在 if 语句之外访问在 if 语句内创建的指针?

How to access a pointer made within an if statement, outside of it?

我正在制作一个简单的程序来根据用户选择的宠物小精灵播放特定的战斗呼叫。我有一个主要 class(Pokemon class)和两个 classes,它们从主要 class 继承了一个虚拟 battleRoar() 函数。 这是代码

#include <iostream>
using namespace std;

class Pokemon{
public:
    virtual void battleCall(){
    }
    virtual ~Pokemon() {}
};

class Weedle: public Pokemon{
public:
    Weedle(){
        cout << "Weedle Weedle!" << endl;
    }
    void battleCall(){
        cout << "-v- weedle" << endl;
    }
};

class Pikachu: public Pokemon{
public:
    Pikachu(){
        cout << "Pikaaaachu!" << endl;
    }
    void battleCall(){
        cout << "pikachu!!" << endl;
    }

};


int main(){

    cout << "Please pick a pokemon." << endl;
    cout << "1. Weedle" << endl;
    cout << "2. Pikachu" << endl;
    int a;
    cin >> a;
    if (a == 1){
        cout << "You picked a weedle!" << endl;
        Weedle chosenPoke;
        Pokemon *p1 = &chosenPoke;

    }
    else if (a == 2){
        cout << "You picked a pikachu!" << endl;
        Pikachu chosenPoke;
        Pokemon *p1 = &chosenPoke;
    } else { cout << "Invalid choice" << endl;}
    cout << "Would you like to hear your pokemon's battle call?" << endl;
    cout << "Yes or No" << endl;
    string choose;
    cin >> choose;
    p1->battleCall();       //produces error: use of undeclared identifier 'p1




    return 0;
}

我遇到的问题是指向子 class 的主要 class 指针在条件之外不再可访问。在这种情况下,我知道在条件语句的每个分支中调用 roar 会很简单。但是,我希望能够调用使用指针创建的任何子class,而不是为条件的每个变体创建调用函数。

if块之前声明指针并更改你想要的对象的创建return。

Pokemon *p1;
if (a == 1){
        cout << "You picked a weedle!" << endl;
        /* Weedle chosenPoke;  -- don't construct the object on the stack */
        p1 = new Weedle();
}
...
p1->battleCall();
delete p1;
...

这解决了未声明标识符的直接问题,但增加了当不再需要对象时必须删除该对象或更改代码以使用智能指针的负担。

虽然主要问题已经得到解答,但您在应用答案时可能会遇到问题。指针 p1 未设置为任何可能导致分段错误的有效值。

你必须这样做:

std::unique_ptr<Pokemon> p1;

if (a == 1) {
    cout << "You picked a weedle!" << endl;
    p1 = std::make_unique<Weedle>();
} else if (a == 2){
    cout << "You picked a pikachu!" << endl;
    p1 = std::make_unique<Pikachu>();;
} else { cout << "Invalid choice" << endl;}

cout << "Would you like to hear your pokemon's battle call?" << endl;
cout << "Yes or No" << endl;
string choose;
cin >> choose;

// In case of invalid input, it'll work!!!
if (p1 != nullptr) {
    p1->battleCall();
}

您可能会发现,尽管 main() 还不是一个复杂的函数,但将其分解为更小的函数可以让您更合理地确定变量范围。

例如

std::unique_ptr<Pokemon> 
create(int choice)
{
    std::unique_ptr<Pokemon> result;

    if (choice == 1)
    {
        std::cout << "You picked a weedle!" << std::endl;
        result = std::make_unique<Weedle>();
    }
    else if (choice == 2)
    {
        std::cout << "You picked a pikachu!" << std::endl;
        result = std::make_unique<Pikachu>();
    } 
    else 
    { 
        std::cout << "Invalid choice" << std::endl;
    }

    return result;
}

完整的工作示例:

http://coliru.stacked-crooked.com/a/8e20a47e0d5e1de5