访问带有访问器的静态std :: set是明智的还是我应该直接访问它?

时间:2013-08-06 14:19:00

标签: c++ static accessor stdset

这个问题是从这个结果得出的: How to automatically maintain a list of class instances?

参考上一个问题,我创建了静态对象列表static std::set< Object* > objects;

但是,为避免EngineObject之间的循环引用,我将其从Engine移出并进入单独的头文件。然后我意识到,不是直接与列表交互,我可以使用一堆静态访问器。这样,如果对列表进行任何更改,我总是可以打破这些功能。

这样做有什么其他好处吗?或者这是一个不好的方法?我永远不打算实例化ObjectManager - 如果我使用我认为被称为'自由函数'而不是管理这个std::set,没有类?

我已经创建了一个测试项目,以便在测试时保持简单。 Inheritor类继承自Object类。 ObjectManager类的代码(在这种情况下由Main.cppObjectInheritor引用,但在我的主项目中将使用非常类似的代码)如下所示:

ObjectManager.h

#include <set>

class ObjectManager
{
    friend class Object;
    friend class Inheritor;

public:
    static int ObjectCount();
    static void AddObject(Object *);
    static void RemoveObject(Object *);

    static int InheritorCount();
    static void AddInheritor(Inheritor *);
    static void RemoveInheritor(Inheritor *);

    static std::set<Object *>::iterator GetObjectListBegin();
    static std::set<Object *>::iterator GetObjectListEnd();

    static std::set<Inheritor *>::iterator GetInheritorListBegin();
    static std::set<Inheritor *>::iterator GetInheritorListEnd();
private:
    ObjectManager();
    ~ObjectManager();
};

ObjectManager.cpp

#include "ObjectManager.h"

static std::set<Object *> objectList;
static std::set<Inheritor *> inheritorList;

ObjectManager::ObjectManager()
{

}
ObjectManager::~ObjectManager()
{
}

int ObjectManager::ObjectCount()
{
    return objectList.size();
}

void ObjectManager::AddObject(Object *input)
{
    objectList.insert(input);
}

void ObjectManager::RemoveObject(Object *input)
{
    objectList.erase(input);
}


int ObjectManager::InheritorCount()
{
    return inheritorList.size();
}

void ObjectManager::AddInheritor(Inheritor *input)
{
    inheritorList.insert(input);
}

void ObjectManager::RemoveInheritor(Inheritor *input)
{
    inheritorList.erase(input);
}

std::set<Object *>::iterator ObjectManager::GetObjectListBegin()
{
    return objectList.begin();
}

std::set<Object *>::iterator ObjectManager::GetObjectListEnd()
{
    return objectList.end();
}

std::set<Inheritor *>::iterator ObjectManager::GetInheritorListBegin()
{
    return inheritorList.begin();
}

std::set<Inheritor *>::iterator ObjectManager::GetInheritorListEnd()
{
    return inheritorList.end();
}

**

编辑:

** 我已经重写了我的代码以消除对ObjectManager的需求。

而不是使用ObjectManager,我想要的每个类都包含其源文件中的静态列表,因此Object.cpp包含static std::set<Object *> objectList;Inheritor.cpp包含{{1} }}

然后,这两个类中的每一个都包含一个静态static std::set<Inheritor *> inheritorList;函数,用于获取其各自列表中的项目数Count()GetListBegin()以获取其开始和结束集。

由于函数在基类和派生类中共享相同的名称,GetListEnd()获取其各自列表中Object::Count()个实例的数量,Object获取的数量为Inheritor::Count()其各自列表中的Inheritor个实例。

我不知道这是不是这样做的坏方法。没有任何东西可以在每个相应课程之外的列表中添加或删除。我唯一的问题是我不确定如何阻止静态函数在任何说法中可用,例如继承自Inheritor

2 个答案:

答案 0 :(得分:0)

如果std::set提供了完全正确的界面,那么您可以直接使用它。如果没有(通常就是这种情况:它有一个非常广泛的接口)那么你应该编写一个类或一组函数来提供你需要的接口,并适当地实现,也许用std::set,也许用其他东西。

答案 1 :(得分:0)

我会把这个集合作为Object类的私有静态成员,它将自己添加到构造函数中的集合中(如果允许的话,不要忘记复制构造函数)。然后创建一个set的只读访问器(返回const引用)。

我不明白你的继承者集的含义。

如果这是游戏引擎中的活动对象列表,我会将其作为引擎类的非静态成员,跟踪其所有对象。