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

C++ 基类指针,访问派生类成员变量?,c++,pointers,inheritance,C++,Pointers,Inheritance,我正在剪切代码以使其更具可读性我希望我不会使其难以理解 class player : public character{ public: // ---------stuff------- protected: // ------stuff-------- vector <item*> inventory; }; class item { public: // -----stuff------------ virtual float get

我正在剪切代码以使其更具可读性我希望我不会使其难以理解

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;
};
职业玩家:公众人物{
公众:
//------东西-------
受保护的:
//----东西--------
病媒清查;
};
类项目{
公众:
//----东西------------
虚拟浮点getHealth(){};
虚拟int getDef(){return 0;};
虚拟int getAttAcc(){return 0;};
虚拟int getAttPow(){return 0;};
虚拟~item();
受保护的:
字符串名;
字符串类型;
int值;
整数权重;
};
职业武器:公共物品{
公众:
武器(int attPow、int attAcc、int inValue、int INWARGE、string inType、string inName);
武器(const武器和cWeapon);
int getAttAcc(武器和武器){return attAcc;};
int getAttPow(){return attPow;};
~z~武器(){};
受保护的:
int attAcc;
int attPow;
};
当我需要武器(与库存中的指针一起存储)访问其attAcc和attPow时,我的问题就出现了。
我尝试过的事情: 我尝试添加虚拟函数,然后用派生类更改它们

我试着把它排除在基类之外,但是由于清单是指向项的指针向量,所以它不允许这样做

最初我希望玩家在武器和盔甲上有两个指针,但因为库存是一个无法使用的物品指针


我把我的课程留给了其他的项目,因为我确信一旦我弄明白了其中一个,其他的都是一样的。因为我有3个派生类,所以我需要清单作为指向基类的指针,对吗?

不确定,您想在这里做什么

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

但是,虚函数必须具有相同的参数(aka签名),否则它只会重载基类函数,虚函数机制将无法工作

在您的示例中,函数int-wearm::getAttAcc(武器和武器)不会重写基类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();
}
//仅对武器类型对象成功施放。
如果(武器*武器=动态施法(物品)){//武器
武器->获取攻击();
}

最直接的错误是您声明了int-wearm::getAttAcc(武器&),其签名与虚拟函数int-item::getAttAcc()不匹配。因为它们不匹配,所以您没有重写基类中的函数

更根本的是,类项声明只属于类项的有意义的函数是没有意义的。(当然,除非它们是有意义的。装甲类型的物品是否也有attPow和attAcc?)

也就是说,不要将getAttAcc(我假设它是“获取攻击准确度”的缩写)作为类项的虚拟函数,除非每个项都可以用于攻击

相反,在查看库存时,如果您只想对武器执行某些操作,请使用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() ...
    }
职业武器:公共物品{
公众:
int getAttAcc(){return attAcc;};
...
}
项目*项目=。。。;
如果(武器*aWeapon=动态施法(anItem)){
…使用aWeapon->getAttAcc()执行某些操作。。。
…和/或使用aWeapon->getAttPow()。。。
}

请看,您需要知道何时以及需要以某种方式投射哪些对象。我正在研究投射,但我不太确定在这种情况下它将如何工作。是否可以使用浇铸指针指向我的库存中的项目?我的意思是,如果库存[1]是一件武器,我可以使用一个带壳的点来指向它以获得访问权限?是的,但你需要确保它在施放时是一件武器。只要使用
如果(武器*武器\u ptr=dynami\u cast(物品)){武器\u ptr->getAttAcc()}
。与手动添加
getItemType
函数相比,它更安全,输入更少。您的另一点是正确的。在C++中使用C样式的Casic是一种坏的形式,在处理多态类型时是危险的。而是使用C++的铸造操作符。在这种情况下,
dynamic\u cast
是正确的方法。“但是,虚拟函数需要具有相同的参数,其他方式它不算作虚拟函数。”应替换为“但虚拟函数只能由具有相同签名的函数重写。”。否则,这只是一个过载。“我试过使用5gon12eder的编码,它以前给了我一个预期的主表达式。”。知道为什么吗?是的,我纠正了dinami错误编辑:没关系,我明白了…愚蠢的错误你们这些家伙/女孩太棒了,非常感谢,我想我现在明白了…再次感谢!