我正在尝试实践多态性和OOD原则[在C++中].需要指导和回答几个问题

Sli*_*ims 0 c++ oop polymorphism sdl virtual-functions

我正在编写一个以RPG元素迷宫为中心的简单2D游戏.它主要用于学习目的,用于练习类设计,图论算法,数据结构使用和使用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
Run Code Online (Sandbox Code Playgroud)

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

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

我意识到这很多,我感谢任何帮助.我真的想了解OOD以及如何使用多态,所以来自一些专家的帮助会非常有用.

再次感谢.

编辑:大问题我也是开始能够修改派生类中的私有数据成员的问题.如果我需要这样做,我听说这是糟糕的课堂设计,我猜我不知道如何编写一个好的界面.

E_n*_*ate 6

部分问题依赖于意见问题.然而:

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