2011-05-20 299 views
2

我试图学习C++(目前只知道PHP和一些C#),并遇到我的第一个问题。C++标识符“_var”未定义

我想调用一个开关内的类,然后在开关后使用该定义的变量。但是,我收到标题中描述的错误。

#include <iostream> 
#include <string> 

using namespace std; 

class Hero { 
protected: 
    int hHealth,hStamina,hExp; 
    string hName; 
public: 
    void Create(string); 
    string GetName() { 
     return this->hName; 
    } 
}; 

class Wizard:public Hero { 
public: 
    void SetStats(string hName) { 
     this->hName = hName; 

     this->hHealth = 40; 
     this->hStamina = 80; 
    } 

}; 

int main() { 
    string hName; 
    int hClass; 


    cout << "Welcome to Ryan's Dungeons & Dragons Adventure!\n\n"; 
    cout << "Enter your Heroes name\n"; 
    cout << "Name: "; 
    cin >> hName; 

    cout << hName << ", please select your class\n"; 
    cout << "(1) The Wizard\n"; 
    cout << "(2) The Warrior\n"; 
    cout << "(3) The Rogue\n"; 
    cout << "(4) The Priest\n"; 

    cout << "Class: "; 
    cin >> hClass; 

    switch (hClass) { 
    case 1: 
     Wizard _hero; 
     break; 
    } 

    cout << _hero->GetName(); 


    system("PAUSE"); 
    return 0; 
} 

在考虑中的错误就行发生:

COUT < < _hero->的getName();

它说_hero是不确定的。

+1

你需要的是一个工厂,返回你的“CharacterClass” /英雄基类的智能指针。当给定1(或用于指示“向导”的任何内容)时,工厂将返回Wizard类的实例。并给这个基类一个虚拟的析构函数。 – 2011-05-20 02:29:25

+0

如果C++允许的话,那将是非常酷的......会节省很多头痛......有时候,C++的严格类型安全性是一种痛苦。 :P – Xeo 2011-05-20 02:37:00

回答

4

_hero仅在switch声明的范围内定义。您需要在与您使用它们相同或更高的范围内创建对象。你能解决这个

一种方法是switch(初始化为null)之前定义一个指针英雄,然后将其设置为switch内的值。例如:

Wizard *_hero = NULL; 
switch (hClass) { 
    case 1: 
     _hero = new Wizard(); 
     break; 
    } 
} 

if (_hero) { 
    cout << _hero->GetName(); 
} 

您也正在使用类值的->(而不是一个指针)。抛开范围问题,你可能打算编写_hero.GetName()。在你的课堂内部,->是正确的,因为this是一个指向你的对象的指针。

+0

为什么这是一个指针? – 2011-05-20 02:30:00

+0

+1,用于很好地解决范围问题。 – 2011-05-20 02:30:59

+0

因为您需要在创建不同范围内的实际类之前创建对类的引用。你只能用指针来实现这一点。 (参考文献必须初始化,不能更改) – yan 2011-05-20 02:31:10

3
switch (hClass) { 
    case 1: 
     Wizard _hero; 
     break; 
} // <-- _hero is deallocated at this point 

cout << _hero->GetName(); 

_hero的范围仅限于switch语句。

+5

你是指switch语句。 – Xeo 2011-05-20 02:27:28

+0

有没有办法完成我想要的,或者我应该尝试一种不同的方法? – Morgan 2011-05-20 02:28:41

+0

@Xeo - 是的,你是对的。如果开关情况**遗漏**,应该可以使用。如何,想一想'情况2'是匹配的情况,并且正在使用实例。 – Mahesh 2011-05-20 02:30:15

0

_hero对象仅限于switch块的范围。你想要什么大概是这样的:

Hero* _hero; 

switch (hClass) { 
case 1: 
    _hero = new Wizard(); 
    break; 
} 

cout << _hero->GetName(); 
+0

你忘记了指针上的星号。 – Xeo 2011-05-20 02:33:25

+0

@Xeo:谢谢你,修好了! – Ryan 2011-05-20 02:35:54

+0

当我尝试这个时,错误消失,但是当我尝试调试时,我得到一个关于未解决的外部错误 – Morgan 2011-05-20 02:50:08

1

我不认为,即使工作在C#...你想那是什么回事在switch语句来初始化一个指针:

Hero* _hero = 0; 

switch(hClass){ 
    case 1: _hero = new Wizard; 
    break; 
} 

// use _hero ... 

// at the end, delete it 
delete _hero; 

尽管如此,你现在很可能需要一个虚拟析构函数和虚函数。阅读它们,它们是一个强大的面向对象功能。但是你可能从C#知道他们。

1

你说你知道一些C#和PHP,我不知道。我只想知道这会在C#中表现如何。

在某个范围内创建一个对象并在范围外使用它。像:{int a;} a = 0;

在C++中它是一个问题。

switch (hClass) { 
    case 1: 
     Wizard _hero; 
     break; 
    } 
//At this no _hero is present. _hero is out of its scope