我一直试图想出最好的方式来分发我的游戏代码的一部分,但不是全部,以便允许人们修改游戏而不是使用我的代码创建独立游戏。这是有多少游戏已经运行,例如Doom3 - 在GPL发布之前,SDK只是为不可修改的EXE创建DLL的代码的一部分。
为此我成功地将我的代码拆分为EXE / SDK,但我担心的是EXE引用了SDK中的类。举个例子,如果我编译EXE,它有一个Entity类型的对象数组,那么在SDK中声明了Entity,然后我去向该类添加另一个成员变量,编译DLL,然后运行旧的EXE新的DLL,这是不是意味着EXE有关于实体大小的错误信息?
还是我过度思考这个?
答案 0 :(得分: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;
};
这些当然不是你唯一可能关注的问题,但应该给你一些“这是你用来解决问题的东西”的想法。