基类指针,访问派生类成员变量?

时间:2014-12-07 02:39:29

标签: c++ pointers inheritance

我正在削减代码以使其更具可读性我希望我不要让这很难理解。

class player : public character{
public:
    // ---------stuff-------

protected:
    // ------stuff--------
    vector <item*> inventory;
};

class item {
public:
    // -----stuff------------

    virtual float getHealth(){};
    virtual int getDef(){return 0;};
    virtual int getAttAcc(){return 0;};
    virtual int getAttPow(){return 0;};
    virtual ~item();
protected:
    string name;
    string type;
    int value;
    int weight;

};

class weapon : public item{
public:
    weapon(int attPow, int attAcc, int inValue, int inWeight, string inType, string inName);
    weapon(const weapon& cWeapon);
    int getAttAcc(weapon& weapon){return attAcc;};
    int getAttPow(){return attPow;};
    ~weapon(){};
protected:
    int attAcc;
    int attPow;
};

当我需要武器(存放在库存中的指针)来访问其attAcc和attPow时,我的问题就来了。
我试过的事情: 我尝试添加虚函数,然后使用派生类更改它们。

我尝试将其从基类中删除,但由于库存是指向项目的指针的向量,因此它不允许它。

最初我希望玩家拥有2个武器和装甲指针,但是因为库存是一个无效的物品指针。

我将我的课程留给了其他项目,因为我确定一旦我把它想出来,其他项目是相同的。因为我有3个派生类,我需要库存作为指向基类的指针吗?

2 个答案:

答案 0 :(得分:2)

不确定,你想在这做什么。

如果你想使用虚函数,那么在派生类中使用virtual关键字也是一件好事。

但是,虚函数必须具有相同的参数(又称签名),否则它只会重载基类函数,虚函数机制将无效。

在你的例子中,函数int weapon :: getAttAcc(weapon&amp; weapon)不会覆盖基类int item :: getAttAcc(),因为初始函数没有参数。

你可以在int item :: getAttAcc(武器和武器)中添加一个参数,如果这是你想要的。

另一个解决方案是添加一个类型函数:

class Item {
   public:
     virtual int getItemType() = 0; // this will make function pure virtual
};

class Weapon : public Item {
   public:
     virtual int getItemType() { return 1; }
     int getAttAcc() {return attAcc;}
}

Item * item = // something
if (item.getItemType() == 1) // weapon
{
   Weapon * weapon = (Weapon)item;
   weapon->getAttAcc();
}

或者,正如其他评论员所建议的那样。更多C ++方式:

// cast will be successful only for Weapon type object.
if (Weapon * weapon = dynamic_cast<Weapon *>(item)) { // weapon
    weapon->getAttAcc();
}

答案 1 :(得分:0)

您最直接的错误是您声明了int weapon :: getAttAcc(weapon&amp;),其签名与虚函数int item :: getAttAcc()不匹配。因为它们不匹配,所以您无法覆盖基类中的函数。

更重要的是, class item 声明只有类武器的有意义的函数是没有意义的。 (当然,除非它们是有意义的。盔甲类型的物品是否也有attPow和attAcc?)

也就是说,除非每个项目都可以使用,否则不要将getAttAcc(我认为是&#34;获得攻击准确性&#34;)的简称为 class item 的虚函数用于攻击

相反,在浏览您的广告资源时,如果您想要仅为武器做某些事情,请使用dynamic_cast检查类型。例如:

class weapon : public item {
public:
    int getAttAcc() { return attAcc; };
    ...
}


item *anItem = ...;

if (weapon* aWeapon = dynamic_cast<weapon*> (anItem)) {
    ... do something with aWeapon->getAttAcc() ...
    ... and/or with aWeapon->getAttPow() ...
    }