C++ C++;双指针成员访问
C++(Arduino包装器)问题:我正在Arduino上编写一个射击游戏,它有一个LCD连接- 我有一个基类(C++ C++;双指针成员访问,c++,pointers,double,member,C++,Pointers,Double,Member,C++(Arduino包装器)问题:我正在Arduino上编写一个射击游戏,它有一个LCD连接- 我有一个基类(Sprite),从这个基类派生出其他的类——Alien、导弹和播放器。Alien类的构造函数也有私有成员pMissile(指向导弹类的指针)-“对象中的对象”应该是描述这一点的一种方式。 [当外星人发射导弹时,它会将自己的(x,y)坐标传递给导弹,并且导弹有自己的方法从外星人的坐标开始移动] 我的问题是:如何通过外星人对象访问导弹的坐标? 下面是简化的代码,我还绘制了类的表示: //
Sprite
),从这个基类派生出其他的类——Alien
、导弹
和播放器
。Alien类的构造函数也有私有成员pMissile
(指向导弹
类的指针)-“对象中的对象”应该是描述这一点的一种方式。
[当外星人发射导弹时,它会将自己的(x,y)坐标传递给导弹,并且导弹有自己的方法从外星人的坐标开始移动]
我的问题是:如何通过外星人
对象访问导弹的坐标?
下面是简化的代码,我还绘制了类的表示:
// Bass class - has a form/shape, x and y position
class Sprite
{
public:
Sprite(unsigned char * const spacePtrIn, unsigned int xInit, unsigned int yInit);
virtual void Move() = 0;
void Render() { display.drawBitmap(x,y, spacePtr, 5, 6, BLACK); }
unsigned int getX() const { return x; }
unsigned int getY() const { return y; }
protected:
unsigned char *spacePtr;
unsigned int x, y;
};
// Derived class "Missile", also a sprite and has a specific form/shape, and specific (x,y) derived from input sprite
class Missile : public Sprite
{
public:
Missile(): Sprite(&spaceMissile[0], 0, 0) {}
virtual void Move(); // its own method of moving
};
// Derived class "Alien" - has a specific form/shape, and specific (x,y) position
class Alien : public Sprite
{
public:
Alien();
virtual void Move(); // its own method of moving
private:
Missile *pMissile;
};
Alien::Alien(): Sprite(&spaceAlien[0], random(5, 75), random(4, 10))
{
Missile MissileArray[MaxAmmoSize];
pMissile = &MissileArray[0];
}
void Alien::Move()
{
if( random(10) % 2 == 0 )
x += 1;
if( random(10) % 3 == 0 )
y += 1;
if( (pMissile != NULL) && (random(10) == 1) )
{
pMissile->setCoord(x, y);
pMissile->Move(); // move the missile
pMissile++; // move onto the next missile in the array
}
Render();
}
/*****************************************************************************************/
Alien MONSTER;
Player HERO;
Alien *pMONSTER = &MONSTER;
void loop()
{
display.clearDisplay();
MONSTER.Move();
HERO.Move();
pMONSTER->getX(); // this is x location of MONSTER
**// how does pMONSTER access pMissile(x,y) within MONSTER.**
delay(100);
display.display();
}
常用的方法是向Alien添加一个getter函数:
class Alien {
public:
Missile* getMissile() { return pMissile; }
}
要使用它:
Alien* a = getAlienFromSomewhere();
auto pMissile = a.GetMissile();
if (pMissile != NULL) {
x = pMissile->getX();
y = pMissile->getY();
}
我想象你想通过外星人进入你的导弹位置来测试与英雄实体的碰撞,但是如果你需要跟踪你的导弹,你不应该像
外星人::Move()
中所示的那样用指针“行走”到下一枚导弹。执行此操作将丢失数组开头的引用
IMHO,我会在你的外星人课上做这样的事情:
// Bass class - has a form/shape, x and y position
class Sprite
{
public:
Sprite(unsigned char * const spacePtrIn, unsigned int xInit, unsigned int yInit);
virtual void Move() = 0;
void Render() { display.drawBitmap(x,y, spacePtr, 5, 6, BLACK); }
unsigned int& getX() const { return x; }
unsigned int& getY() const { return y; }
protected:
unsigned char *spacePtr;
unsigned int x, y;
};
// Derived class "Missile", also a sprite and has a specific form/shape, and specific (x,y) derived from input sprite
class Missile : public Sprite
{
public:
Missile(): Sprite(&spaceMissile[0], 0, 0) {}
virtual void Move(); // its own method of moving
};
// Derived class "Alien" - has a specific form/shape, and specific (x,y) position
class Alien : public Sprite
{
public:
Alien();
~Alien(); // a destructor to cleanup your missiles - arduino have almost no memory to handle leaks ;-)
virtual void Move(); // its own method of moving
inline Missile& getMissile(unsigned char n) { return pMissile[n]; }
inline Missile& operator[](unsigned char n) { return getMissile(n); }
inline unsigned int& getX(unsigned char n) { return getMissile(n).getX(); }
inline unsigned int& getY(unsigned char n) { return getMissile(n).getY(); }
private:
Missile *pMissile;
// adding the code to handle the count
unsigned char missileCount;
};
Alien::Alien():
Sprite(&spaceAlien[0], random(5, 75), random(4, 10)),
missileCount(0)
{
// this way of allocation creates a local object that is destroyed by the end of this scope
//Missile MissileArray[MaxAmmoSize];
//pMissile = &MissileArray[0];
// so you should do somethin like this
pMissile = new Missile[MaxAmmoSize];
}
Alien()::~Alien()
{
delete[] pMissile;
}
void Alien::Move()
{
if( random(10) % 2 == 0 )
x += 1;
if( random(10) % 3 == 0 )
y += 1;
if( (pMissile != NULL) && (random(10) == 1) )
{
// my proposal to fire it up
Missile& missile = pMissile[missileCount];
missile->setCoord(x, y);
missile->Move(); // move the missile
missileCount++; // move onto the next missile in the array
}
Render();
}
使用这样的代码,您可以通过以下方式访问导弹的位置:
MONSTER.getX(0) += 1;
MONSTER[0].getY() +=1;
MONSTER.getMissile(1).getX() = 10;
为了清晰起见,我还建议将
getX()
和getY()
方法重构为x()
和y()
,因为它们返回对类内容的引用(这样做的话,你还应该将你的x
和y
成员重命名为其他名称,否则你可能会因为名称冲突而发疯)。简短的回答是“不会。”你要么需要在Alien中提供一个接口,让你获得pMissile的副本,要么提供一个接口,将请求转发给它。或者,从Alien中取出pMissile,并将其与其他实体同等对待。旁注:Alien等作为sprite的子类,听起来不是很好的设计。Alien等有一个sprite(可能有几个)与它们相关,但它们是游戏对象。听起来合成比继承更好。那么,也可能更容易弄清楚如何按照你的要求去做。