这类似于我确定的其他问题,我通读了。我正在尝试写一个移动课程。我需要一个Player类和一个继承move类的Item类,反之亦然。这就是我遇到的困难。我无法绕过头,或开始工作,这是一种基类没有的方式"移动。"我迷失在这里......
class Player {
protected:
int x;
int y;
int str;
int speed;
int level;
int exp;
public:
Player(int _str, int _speed, int _level, int _exp) { x=0;y=0;str=_str;speed=_speed;level=_level;exp=_exp; }
int GetX() {return x;}
int GetY() {return y;}
int GetStr() {return str;}
int GetSpeed() {return speed;}
int GetLevel() {return level;}
int GetExp() {return exp;}
};
class Move : public Player {
public:
void TryMove(int n) { x += n; }
};
int main(int argc, char *argv[])
{
Player You(101, 5, 3, 43625);
//You.TryMove(5); how?
}
TryMove(5)失败。如果我以另一种方式进行操作,那么他们输入的是Move(?)并且听起来并不正确...
答案 0 :(得分:2)
首先,公共继承意味着IS-A关系。所以 Move
IS-A Player
没有任何意义。你的设计错了。
关于你的错误,这很愚蠢。您正在创建Player
对象You
并在其上调用Move
方法。要使用类Move
的方法,您必须创建Move
(或任何公开派生类)的对象。
class Move : public Player {
public:
//either create a ctor that will pass params to parent ctor, or create an empty ctro in parent class
Move(int _str, int _speed, int _level, int _exp):Player(_str,_speed,_level,_exp){}
void TryMove(int n) { x += n; }
};
int main(int argc, char *argv[]){
Move You(101, 5, 3, 43625);
You.TryMove(5);
}
我会将其设计如下:
class Movable{
public:
virtual bool TryMove()=0;
};
class Player: public Movable {
public:
bool TryMove() override{
//implementation code
}
//other members
};
int main(){
Movable* player = new Player(101, 5, 3, 43625);
player->TryMove();
delete player;
}
答案 1 :(得分:2)
我建议考虑它的方式是Is A
或Has A
成语。那么......玩家是移动吗?可能不是,移动玩家是谁?也可能不是。然后我们试试Has A
。移动有玩家还是玩家有移动?我会说玩家个人移动。这意味着不使用继承,而是让播放器包含Move
类的实例。所以......
class Player{
public:
Move myMove;//where move is defined already as whatever you need it to be.
};
//then your main
int main(int argc, const char** argv){
//...other setup here
Player p;
p.myMove.TryMove(10);
//whatever else...
}
这就是我如何接近你的设计。至于错误...在上面的代码中,您Move
继承了Player
,但您创建了Player
并期望它具有Move
的功能但是它根据您在示例代码中设置的继承,无法获得该功能。
如果您需要澄清我所说的内容或其他任何内容,请告诉我。祝你好运
编辑:
根据您的评论,我建议您使用一个包装函数来获取您需要的值。
class Player{
public:
void TryMove(int i);
private:
Move myMove;
int x;//the value you will be getting from Move::tryMove
};
void Player::TryMove(int i){
this->x = myMove.tryMove(i);//store the value of the function call
//the function obviously won't be a void function in this case
}
还有其他方法可以做到这一点,但这种方式很简单。如果你开始使用继承来解决你的问题,我会Player
从Move
继承,但我仍然支持我原来的答案,我只想帮助进一步解释。