我正在尝试[C++]练习多态性和OOD原则。需要指导和几个问题的答案



我正在写一个简单的2D游戏,以RPG元素的迷宫为中心。它主要用于练习课堂设计、图论算法、数据结构使用和2D图形的使用。

项目简介:

游戏本身是基于瓦片的。它目前在屏幕上生成并绘制迷宫,允许玩家移动,并对墙壁进行碰撞检测;此外,它还可以处理更大迷宫的屏幕滚动。

不管怎样,现在我正在构建一个对象,它可以处理在地图周围放置对象的问题。首先是金币,然后是心形和物品。我认为这将是一个练习继承和多态性的好时机,但我还没有接受过任何此类设计的正式培训。这是头文件:

#ifndef MAP_OBJECT_H
#define MAP_OBJECT_H
#include "Common.h"
#include "Utility Functions.h"
const int TILE_SIZE = 80;
class MapObject
{
public:

    MapObject(unsigned int nClips, unsigned int r, unsigned int c, unsigned int cSize)     :
         sheet(0), clips(0), row(r), col(c), numClips(nClips), clipSize(cSize)
    {
        //For those of you who aren't familiar with sprite sheet usage, basically this
        // handles which part of the sprite sheet your on, so it will draw the correct sprite to the screen
        if(numClips > 0) clips = new SDL_Rect[numClips];
        box.h = clipSize;
        box.w = clipSize;
    }
    virtual ~MapObject()  //NOt sure if this is right.  All the derived classes will
                          // behave the same upon deletion, since the only resource 
                          //  that got allocated was for the box SDL_rect
    {
        if(clips) delete[] clips;
    }

    void initBox(int modX, int modY);
    //I think each object will draw a little different, so I made it virtual
    virtual void draw() = 0;
    //Same with interaction--although I'm not sure how my player class is going to be able to handle this yet
    virtual void interact() = 0;
     SDL_Rect getBox() const;
 private:
    SDL_Surface*  sheet;
    SDL_Rect      box;
    SDL_Rect*     clips;
    unsigned int  row, col;
    unsigned int  numClips;
    unsigned int  clipSize;
     MapObject() {}  //Made this private because I want the memory to be allocated, and 
                     // numClips needs to be initialized for that to happen, so 
                     //basically I'm forcing the user to use the constructor with parameters
};

class Coin : public MapObject
{
    enum  CoinFace  //This represents all the different coin facings in the sprite 
                     //sheet, so that is can animate.  Used in the draw function.
    {
        FRONT,
        TURN1,
        TURN2,
        TURN3,
        USED
    };
    CoinFace  active;
public:
    virtual void draw(SDL_Surface* destination);
    virtual void interact();
};
#endif //MAP_OBJECTS

我最大的问题是一个普遍的问题:这是我设计的一个良好开端吗?他们明显的问题吗?OOD原则/惯例的滥用?

这样定义虚拟析构函数会允许所有派生类使用它吗?或者我需要为每个派生类定义它吗?

我意识到这太多了,我很感激任何帮助。我真的在努力理解OOD和如何使用多态性,所以一些专业人士的帮助会非常有用。

再次感谢。

编辑:我还有一个大问题,就是如何开始修改派生类中的私有数据成员。我听说如果我需要这样做的话,这是糟糕的类设计,我想我不知道如何写一个好的界面。

问题的一部分取决于意见。尽管如此:

  1. 我在这里只能说,你的方法是可行的,而且你正在努力实现这一点。只是不要忘记定义Coin的构造函数
  2. 当我们只有基类类型的指针时,虚拟析构函数的全部目的是调用适当的析构函数。此外,派生析构函数是在自动调用基析构函数之前执行的,而不必显式调用它。在这种情况下,由MapObject*指向的硬币将被按顺序执行~Coin()~MapObject()delete正确销毁
  3. 这个问题很容易变成关于正确接口构建的争论,但以下是一些解决方案:
    • 通过构造函数定义私有成员,防止它们被其他类修改
    • 使基类中的成员为protected,而不是private。这可能是您希望在这里做的事情的更简单的解决方案
    • 为私有成员类型创建setter,如setActive(CoinFace)。您可以根据需要调整这些函数,比如防止对某个属性的无效定义导致整个对象不一致。与前面的解决方案一样,您可以使这些setter受到保护,这样只有派生类才能访问它们
    • 使该类成为另一个类的friend(称其为a)。A的实例可以获取该类的对象并访问其所有私有成员

相关内容

最新更新