首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对象管理-容器还是工厂?

对象管理-容器还是工厂?
EN

Stack Overflow用户
提问于 2011-10-12 10:43:05
回答 3查看 504关注 0票数 1

我即将结束一个游戏编程入门课程,我想把我在课堂上学到的技能和我以前的OOP经验结合起来,创建一个小库来制作2D游戏。不过,我目前关心的是,这是管理类实例集合的最佳方法。

我使用的库(DarkGDK)完全由作用于整数的自由函数组成。当使用像dbSprite()这样的函数创建"object“时,您会给它一个唯一的ID (int值)来引用它--我猜是一种”地址“。我个人认为这种方法是对的,所以我创建了类来封装每一组免费函数,如AnimatedSprite和AnimatedSprite( DarkGDK库中的两种Sprite类型是不同的)。

问题是,为了使这些对象工作,我仍然必须向构造函数传递一个唯一的ID,以便针对适当的地址调用DarkGDK函数。我试图避免使用ID来引用这些东西,但我正在讨论如何创建对象。目前,我有一些AssetManager类保存对创建的每个对象的引用,检查现有的ID,并且只允许惟一的ID,但这仍然不能解决强制生成管理类外部ID的问题。这使我认为工厂是最好的方法。

我知道在C#中我可以创建一个AssetFactory<T> where T:Asset,它可以很容易地为每个资产调用适当的构造函数来创建实例,但据我所知,C++没有这样的工具。

所以我认为我应该采取的方法是使用某种抽象的AssetFactory。我的想法(正确与否)是,AssetFactory的子级将跟踪使用中的is,并且只发出独立对象的唯一is。就像这样:

代码语言:javascript
复制
class Asset {
    int m_index;
    Asset(int index);
};
class Image : public Asset {
    Image(char* imgPath);
    void Draw();
};
class Sprite : public Asset {
    Sprite(Image* img);
    void Draw();
};

class AssetFactory {
private:
    std::vector<Asset*> m_assets;
    int GetUniqueID();
public:
    AssetFactory();
    ~AssetFactory();

    virtual Asset* CreateAsset(); // but each class has different constructor parameters...
};

class ImageFactory : public AssetFactory {
    Asset* CreateAsset(char* imgPath); // ...so this wouldn't work (nor compile)
};
class SpriteFactory : public AssetFactory {
    Asset* CreateAsset();   // ...so will i be forced to call the default constructor and modify it later?
};

这里的问题是,如上所述,不同的对象有不同的构造函数,这使得这个设计变得毫无意义。我应该采取不同的方法吗?还是我对工厂模式有错误的看法?

编辑:为了澄清起见,我希望为雪碧和图片分开工厂的原因是,雪碧和图像具有相同的ID是可以允许的。ID只能在相同“类型”的其他资产中是唯一的。

EN

回答 3

Stack Overflow用户

发布于 2011-10-13 10:27:46

如果您的库允许任意if,并且您在一个相对相等的地址空间中工作(例如,sizeof of (Int) == sizeof of(int*)),这是一个非常简单的问题,在我所知道的几乎所有32位编译器上都是如此。生成ID非常简单--只需reinterpret_cast指针即可。

代码语言:javascript
复制
class Sprite {
    int GetUniqueID() { return reinterpret_cast<int>(this); } // easies
public:
    // public interface
};

此外,重复使用旧ID实际上可能不值得。继续做新的吧。我是说,你不会用32位整数耗尽空间的。

最后,您绝对不能在这里使用运行时继承。如果必须的话,请使用编译时混合。

票数 1
EN

Stack Overflow用户

发布于 2011-10-12 11:08:27

在C#有泛型的地方,C++有模板。您不能很容易地在C++中提供对泛型参数的约束,但是有一些方法可以确保只将从资产派生出来的类型作为模板参数。

为了将适当的参数传递给构造函数,可以使用可变模板方法。我现在没有编译器.稍后我将使用一个示例再次编辑,尽管您可以在堆栈溢出上找到许多其他的可变模板代码。

票数 0
EN

Stack Overflow用户

发布于 2011-10-12 22:38:22

也许我漏掉了什么,我不清楚你为什么不能将ID生成器移到AssetManager中,这样就可以从外部世界隐藏所有唯一ID的痛苦。

无论如何,如果您需要跟踪if,您将需要manager类,据我从您的帖子中可以看出。如果您使用工厂方法而不是工厂类,那么您刚刚到达了终点线:)剩下的唯一问题是in的处理,但是您可以在Asset类的虚拟析构函数中这样做。如果您想保持它的干净,那么您应该在管理器中为它提供一个受保护的方法,并使资产类析构函数(或一些清理函数)成为管理器的朋友。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7738819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档