所以我在一大组对象上执行同样的功能。据我所知,最好将这组对象保存在连续的内存空间中,以便有更好的时间。
std::vector<MyObject> myObjects;
// Fill vector with thousands of objects
for( auto const& obj listMyObjects ) { obj.doThing(); }注意: myObjects存在于应用程序的生命周期中,并且在不断变化。
在我的代码的其他部分中,我想直接使用MyObject的单个实例。通常,我会用像MyObjectManager这样的类包装我的向量,然后做一个getter:
MyObject * obj = MyObjectManager::getObject( "OBJECT_NAME" );
obj->setName( "NEW_NAME" );但这很容易出错,因为如果调整矢量的大小,指针可能会失效。这就让我转而使用索引或id,并通过管理器实现所有更改。
int objId = MyObjectManager::getObject( "OBJECT_NAME" );
MyObjectManager::setObjectName( objId, "NEW_NAME" );但我不认为这是最好的方式,因为它紧密结合我的经理和对象类。因此,我考虑为作为管理器朋友的对象创建一个接口:
class MyObject
{
std::string myName;
}
class MyObjectInterface
{
int myId;
MyObjectInterface( int id ) { myId = id; }
void setName( std::string name ) { MyObjectManager::myObjects.at( myId ).name = name; }
}
class MyObjectManager
{
friend class MyObjectInterface;
static std::vector<MyObject> myObjects;
static MyObjectInterface getObject( std::string name ) { return MyObjectInterface( myObjects.find( name ) ); // Psuedo code }
}
MyObjectInterface obj = MyObjectManager::getObject( "OBJECT1" );
obj.setName( "OBJECT2" );注释:代码中的借口问题。这更多的是关于这个想法,然后是关于代码。
虽然这似乎是可行的,但我很好奇我是否正确地解释了这个问题,以及这个解决方案是否过于复杂?会喜欢一些见解的,谢谢。
发布于 2017-07-24 14:33:55
出于给出的原因,我认为使用索引或id而不是指向向量中对象的长寿命引用的指针是合理的。为了更好的类型安全性,我认为将该id封装在类中也是合理的。
但我通常不会让该类成为真正对象的完整代理。如果vector确实是从多个线程“不断地”更改,那么甚至类似于
MyObjectManager::myObjects.at( myId ).name = name;不安全。在使用at获取对对象的引用和设置名称之间,可以调整vector的大小,并且您的引用可能无效。
您通常需要在性能关键代码中有一些本地保证,即vector不会被调整大小,并且使用引用或指针是安全的。在紧循环中通过id查找对象的成本可能会超过从数据局部性中获得的任何好处。
过度使用MyObjectInterface可能会成为数据局部性的敌人,因为与MyObject不同,它们在内存中不一定是连续的。
如果MyObjectInterface和/或MyObjectManager实际上需要提供复杂的同步机制,那么我建议您发布一个包含这一点的单独问题。
https://stackoverflow.com/questions/45281673
复制相似问题