Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对象管理-容器还是工厂?_C++_Oop_Factory Pattern - Fatal编程技术网

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

C++ 对象管理-容器还是工厂?,c++,oop,factory-pattern,C++,Oop,Factory Pattern,游戏编程入门课程即将结束,我想将课堂上学到的技能与之前的OOP经验结合起来,创建一个用于制作2D游戏的小型库。不过,我目前关心的是,这是管理类实例集合的最佳方法 我使用的库(DarkGDK)完全由作用于整数的自由函数组成。当使用dbSprite()之类的函数创建“对象”时,您会给它一个唯一的ID(intvalue)来引用它——我想是某种“地址”。我个人认为这种方法很有用,所以我创建了一些类来封装每一组自由函数,比如Image、Sprite和AnimatedSprite(这两种Sprite类型在D

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

我使用的库(DarkGDK)完全由作用于整数的自由函数组成。当使用dbSprite()之类的函数创建“对象”时,您会给它一个唯一的ID(
int
value)来引用它——我想是某种“地址”。我个人认为这种方法很有用,所以我创建了一些类来封装每一组自由函数,比如Image、Sprite和AnimatedSprite(这两种Sprite类型在DarkGDK库中是不同的)

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

我知道在C语言中我可以创建一个<代码>资产工厂,其中t:资产可以很容易地调用每个资产的适当构造函数来创建实例,但据我所知C++没有这样的工具。 所以我认为我应该采取的方法是使用某种抽象资产工厂。我的想法(正确与否)是AssetFactory的子级将跟踪正在使用的ID,并且只发布适当的对象唯一ID。大概是这样的:

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?
};
类别资产{
int m_指数;
资产(国际指数);
};
类别形象:公共资产{
图像(字符*imgPath);
无效抽取();
};
类精灵:公共资产{
精灵(图像*img);
无效抽取();
};
类资产工厂{
私人:
std::向量m_资产;
int GetUniqueID();
公众:
资产工厂();
~AssetFactory();
虚拟资产*CreateAsset();//但是每个类都有不同的构造函数参数。。。
};
类ImageFactory:公共资产工厂{
Asset*CreateAsset(char*imgPath);/…所以这不起作用(也不编译)
};
类别SpritFactory:公共资产工厂{
Asset*CreateAsset();/…那么我将被迫调用默认构造函数并在以后修改它吗?
};
这里的问题是,如上所述,不同的对象有不同的构造函数,这使得这个设计没有意义。我应该采取不同的方法吗?还是我对工厂模式有错误的想法

为了澄清,我希望单独的工厂用于精灵和图像是因为它可以被一个精灵和一个图像所拥有的ID相同。IDS必须在同一类型的其他资产中唯一的。< /P> < P>其中C有泛型,C++有模板。您不能轻易地在C++中提供泛型参数的约束,但有一些方法可以确保只将一个派生类型的派生变量作为模板参数。 为了将适当的参数传递给构造函数,可以使用可变模板方法。我现在没有可用的编译器。。。稍后我将再次以一个例子来编辑,尽管您可以在StAdvExcel中找到大量其他的可变模板代码。

< P>其中C语言有泛型,C++有模板。您不能轻易地在C++中提供泛型参数的约束,但有一些方法可以确保只将一个派生类型的派生变量作为模板参数。
为了将适当的参数传递给构造函数,可以使用可变模板方法。我现在没有可用的编译器。。。稍后我将用一个示例再次进行编辑,尽管您可以在stackoverflow上找到大量其他可变模板代码。

也许我遗漏了什么,我不清楚您为什么不能在AssetManager中移动ID生成器,这样就可以将唯一ID的所有痛苦隐藏起来


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

也许我遗漏了什么,我不清楚你为什么不能在AssetManager中移动ID生成器,通过这种方式,可以向外界隐藏独特ID的所有痛苦


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

如果您的库允许任意ID,并且您在相对相等的地址空间(例如sizeof(int))中工作,那么这是一个很容易解决的问题==sizeof(int*),这在我所知道的几乎所有32位编译器上都是正确的。生成ID很简单——只需重新解释指针即可

class Sprite {
    int GetUniqueID() { return reinterpret_cast<int>(this); } // easies
public:
    // public interface
};
类精灵{
int GetUniqueID(){return reinterpret_cast(this);}//