【问题标题】:How to automatically maintain a list of class instances?如何自动维护类实例列表?
【发布时间】:2013-08-03 15:05:15
【问题描述】:

在我的 C++ 项目中,我有一个 Engine 类和一个 Object 类。

我的问题在于我的 Object 实例是如何创建的。目前这是通过在Engine 类中使用CreateObject(parameters) 函数来完成的。这会将 Object 的新实例添加到 std::vectorObject 实例中。

我想在我的Engine 类中维护Object 的实例列表,但不需要CreateObject(parameters) 函数。我这样做的原因是我可以创建可以从Object 继承但仍被添加到此列表中的新类。此列表的原因是(在 Engine 中)我可以遍历每个已创建的 Object 实例。

这最终意味着我使用Object newObject = Object(parameters); 之类的东西创建我的Object 实例,但仍然让Engine 类维护所有Object 实例的列表,而无需Object 引用Engine 的实例或将自身添加到此列表的列表(如 Object 的实例不应该知道它所在的列表)。 可以这样做吗?

【问题讨论】:

  • 如果不创建 Engine static 的实例或单例(无论如何这是一种“静态”的美化方式)或让对象本身维护自己的静态列表,就无法做到这一点实例,并授予 Engine 对该列表的访问权限。
  • 如何将Object的实例保存在Engine类的静态向量中,并使用静态公共函数推送Object实例?您可以在 Object 类的构造函数中调用它。
  • 对于仅存储对象实例的问题,也许可以看看我对问题c++ storing an object into an array of objects within the constructor of that object 的回答,这是尝试使用更现代的指针。

标签: c++ list class instance stdvector


【解决方案1】:

您可以在 Engine 类中定义一个静态集合数据成员,在您的 Object 构造函数和析构函数中更新它:

class Engine
{
    friend class Object;
...
public:
    static std::set< Object* > m_instances;
};

class Object
{
public:
    Object();
    virtual ~Object();
    ...
};

在构造函数中递增,在析构函数中递减。

Object::Object()
{
    Engine::m_instances.insert(this);
}

Object::~Object()
{
    Engine::m_instances.erase(this);
}

【讨论】:

  • 我认为您希望将 m_instances 声明为静态。
  • 这是好的做法吗?这样做有什么缺点吗?
  • 此外,您的答案看起来与 Joseph Pla 和 mag_zbc 的非常相似,只是您使用 std::set 而不是 std::vector。我以前从未使用过std::set,除了您显然在这里将其用作容器这一事实之外,我对它一无所知(稍后我有时间会查找它是什么)。您是否有理由在std::vector 的情况下使用它?还是只是个人喜好?
  • @Interminable,是的,因为您可能有很多实例,并且可能以与分配它们不同的顺序删除它们。在集合中查找要删除的元素更快。
  • 好吧。最后一个问题——你为什么要把析构函数变成虚拟的?
【解决方案2】:

我认为您的工厂模式方法是实现这一目标的好方法。引擎在内部管理对象的所有实例。

但是如果你想创建外部实例,也由引擎管理,你必须访问引擎的一个实例;即使该实例是一个全局变量,即使 Engine 类实现了单例模式。

第二个最好的方法(第一个是你还要做的,工厂),我认为是在引擎中实现一个单例:

class Object
{
    Object
    {
        Engine::instance().addObject( this ); //Note that engine stores pointers. STL containers cannot store references.
    }

    ~Object
    {
       Engine::instance().releaseObject( this );
    }
};

【讨论】:

    【解决方案3】:

    使用静态

        vector<Object*> Objects
    

    Engine 类中的变量和静态公共函数

        Push(Object* obj) { Objects.push_back(obj); }
    

    将对象推送到列表中。然后在你的 Object 类的构造函数中你会调用

        Engine::Push(this)
    

    【讨论】:

      【解决方案4】:

      就像许多人提到的那样,工厂架构是一种不错且干净的方式,否则您将不得不拥有一个全局实例、静态成员或单例。但是,静态方法是 使Object 成为类引擎的friend 并使成员静态:

      class Engine{
           friend class Object;
      
           private:
           static std::vector <Object*> objectList;
      };
      

      这将允许 Object 静态访问 Engine 的私有成员。然后在 Object 的构造函数中,将其添加到列表中,如下所示:

      Object::Object(int randomparam1, const char* randomparam2)
      {
          Engine::objectList.push_back(this);
      }
      

      【讨论】:

        猜你喜欢
        • 2015-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-18
        • 1970-01-01
        • 2021-02-19
        • 2012-05-22
        • 1970-01-01
        相关资源
        最近更新 更多