2015-11-05 197 views
0

我正在尝试编写一个非常简单的编程语言,让某人在Flex/Bison中为某个学校项目玩一个战舰游戏。为了存储我的变量,我有一个名为symbol_table的映射,它为该键提供一个字符串,并为其值赋予一个变量*。继承树如下:C++ dynamic_cast基类指向派生类指针的指针

class Expression { 
public: 
    Type type; 
    virtual ~Expression(){} //to make it polymorphic 
}; 

class Variable : virtual public Expression { 
public: 
    char* name; 
    Variable* next; 

    virtual ~Variable(){ //also for polymorphism 
     delete name; 
     delete next; 
    } 
}; 

class Player : virtual public Variable{ 
public: 
    std::string playerName; 
    std::vector<GameBoat> playerBoats; 
    Grid opponentGrid; 
    Grid playerGrid; 

    Player(std::string playerName){ 
     this->playerName = playerName; 
    } 

    bool addBoat(std::string boatName, char scolumn, int srow, bool vertical){ 
     //make new boat here and then push it back to the vector 
     GameBoat newBoat(boatName);   //this works --> makes a valid boat 
     if(newBoat.assignedValue){ 
      playerBoats.push_back(newBoat); //SEGMENTATION FAULT HAPPENS HERE 
      return true; 
     }else{ 
      return false; 
     } 
    } 
}; 

class Computer : public Player{ 
public: 
    Computer(std::string playerName) : Player(playerName){} 
}; 

一切都很正常,当我把球员指针和计算机指针到地图,但是当我尝试检索这些值再次使用的dynamic_cast的基础变量*垂头丧气的球员*或计算机*,所播放的播放器*或计算机*的所有属性均为NULL,因此会给我一个“分段错误:11”错误。但是,我可以访问Player和Computer类中的类方法。

Variable* var = get_symbol($1); 

    if (var == NULL) { 
     sprintf(errormsg, "%s not found.\n", $1); 
     yyerror(errormsg); 
    }else if(var->type == PlayerType){ 
     Player* myPlayer = dynamic_cast<Player*>(var);  //Cast var to Player* 
     myPlayer->addBoat("aircraftcarrier", 'a', 1, true); //Enters this function 
    }else if(var->type == ComputerType){ 
     Computer* myComputer = dynamic_cast<Computer*>(var); //Cast var to Computer* 
     myComputer->addBoat("aircraftcarrier", 'a', 1, true); //Enters this function 
    } 

我该如何访问派生类的方法,但无法访问派生类的属性?我使用多态,dynamic_cast不返回NULL值(否则程序将永远不会进入函数并立即给出分段错误)。

+0

您正在创建一种编程语言,仅用于创建战舰游戏? –

+0

这是一个学校项目。这是重点。 – tdon

+1

您能否提供[最小,完整和可验证的示例](http://www.stackoverflow.com/help/mcve)?我不知道问题是什么。 – Barry

回答

0

addBoat函数不是虚拟的,因此在调用它之前不需要对myPlayer或myComputer进行取消引用,因此在函数稍后才能获得segfault。

所有成员函数都有一个隐含的this参数。您可以将addBoat视为等效于免费功能bool addBoat(Player* this, std::string boatName, char scolumn, int srow, bool vertical)this没有什么特别的,直到你真的在函数中取消引用为止。

为了解决实际问题,您应该在调用函数之前检查myPlayer和myComputer是否为NULL。

+0

如果'this'为NULL,那么发生了一些不好的事情。 –

+0

很明显,但它不是取消调用成员函数。这就是段错误发生的原因 – Kevin

+0

它被解除引用。 'mem_func();'是'this-> mem_func();' –

相关问题