1

我一直在尝试想出最好的方法来分发我的游戏代码的一部分,但不是全部,以便允许人们修改游戏但不使用我的代码创建独立游戏。这就是有多少游戏已经运行,例如 Doom3 - 在 GPL 发布之前,SDK 只是为不可修改的 EXE 创建 DLL 的代码的一部分。

为此,我成功地将我的代码拆分为 EXE/SDK,但我担心的是 EXE 引用了 SDK 中的类。例如,如果我编译具有 Entity 类型对象数组的 EXE,则在 SDK 中声明 Entity,然后我将另一个成员变量添加到该类,编译 DLL,然后运行旧的 EXE新的 DLL,这是否意味着 EXE 包含有关实体大小的错误信息?

还是我想太多了?

4

1 回答 1

1

“如果您修改此类,它将无法与其他地方定义的类一起使用。

这些问题也有很多解决方案。

通常使用(智能)指针和/或引用而不是类本身来形成接口,以避免代码的两个部分必须就类的大小达成一致。

因此,例如,而不是:

class EntityCollection
{
  private:
   vector <Entity> entities;
  public:
   void addEntity(Entity e) { entities.push_back(e); }
   void removeEntity(Entity e) { ... } 

};

我们将使用指针样式存储(应该真正使用智能指针,但为了简短起见,我不是):

class EntityCollection
{
  private:
   vector <Entity*> entities;
  public:
   void addEntity(Entity* e) { entities.push_back(e); }
   void removeEntity(Entity* e) { ... } 

};

现在,无论实体有多大,或者它包含什么,它在向量中仍然是“指针大小的”。

另一个变体是有一个“pimpl”接口。你有一个主类定义,里面是一个(智能)指向实现类的指针,它提供了一组已知的虚函数。

像这样的东西:

class Entity
{
   public:
     class EntityImpl 
     {
        virtual int func()  = 0;
        ...
     };
     Entity(EntityImpl* impl) pImpl(impl) {}
     ...
     int func() { return pImpl->func(); }
   private:
     EntityImpl* pImpl;
};

这些当然不是您唯一可能关心的问题,但应该给您一些“这是您用来解决问题的东西”的想法。

于 2013-06-24T16:20:50.970 回答