我有两个对象向量:
std::vector<Foo*> fooVector; //contains some 100 elements
std::vector<Bar*> barVector; //contains some 10,000 elements
这个想法是,总有比Foo对象多得多的Bar对象。但是,每个Foo对象都需要与Bar对象相关联;到目前为止,这就像为每个Foo对象提供一个Bar指针和一个getBar()函数一样简单。
然而, 我需要能够做相反的事情 :给定一个Bar对象,我需要一种方法来立即获得其关联的Foo,如果有的话任何。实现这一目标最直接的方法是给每个Bar一个Foo指针。这似乎是非常多余的,因为我会引入10,000多种方法来解决问题(更不用说其中只有100种是有效的,其余的都是无效的)。我现在拥有的另一种方式是这样的:
Foo* getFooPtr(Bar* barObj){
for(auto& foo : fooVector){
if(foo->getBar() == barObj)
return foo;
}
}
虽然它有效但效率很低,因为每次都必须遍历整个fooVector。此功能需要经常运行,因此这是不可接受的。
我考虑使用类似std :: map的东西,但最终仍然存在相同的迭代问题。
答案 0 :(得分:3)
[...]到目前为止,这就像为每个Foo对象提供一个Bar指针和一个getBar()函数一样简单。
在这种情况下,这个:
Foo* getFooPtr(Bar* barObj){
for(auto& foo : fooVector){
if(foo->getBar() == barObj)
return foo;
}
}
很疯狂。
如果您为每个Foo
对象指定一个Bar
指针,为什么不给每个Bar
一个Foo
指针?
class Foo
{
protected:
Bar* _bar;
public:
void setBar(Bar* bar);
Bar* getBar() const;
};
class Bar
{
friend class Foo; //allow Foo to set _foo pointer
protected:
Foo* _foo;
public:
Foo* getFoo() const;
};
void Foo::setBar(Bar* bar)
{
this->_bar = bar;
bar->_foo = this;
}
Bar* Foo::getBar() const
{
return this->_bar;
}
Foo* Bar::getFoo() const
{
return this->_foo;
}
每次将Bar
对象与Foo
对象关联时,两者都会自动保存此关联 - 您将能够从Bar
得到Foo
指针亦然:
Foo* f = ...;
f->setBar(...);
现在:
Bar* b = f->getBar();
Foo* bf = b->getFoo();
assert( f == bf ); //This hould always be true
答案 1 :(得分:1)
10,000个元素的向量不会超过10,000种出错的方式&#34;。如果你对所有元素做同样的事情,它只会一个更多的方法来解决问题 - 填充指针数据的代码。
如果没有更好的方法,我会选择双重链接,如果我对问题的看法更广泛,我只能设计。有了这个更广泛的视角,可能存在更好的选择,可能涉及集合和地图 - 特别是如果你需要对一个酒吧的foo和一个foo的酒吧进行密集搜索。
将指针设置封装在一个函数中,以确保该对是一致的,并且您将是安全的。
特别是,您应该尝试该选项,看看它是否会给您带来特定问题。 StackOverflow将在这里解决它们。
您可以修复错误,但您无法修复尚未编写的代码,以免出错。
答案 2 :(得分:1)
如果您不太关心空间复杂性并且时间复杂性是您主要关注的问题,那么您可能希望实现哈希表。
查找将是O(1),因为你没有桶,并且与存储10.000指针相比,你可能会使用更少的内存(它们是否为null)。
答案 3 :(得分:0)
如果您需要减少冗余,请创建另一个向量
std::vector<std::pair<Bar *, Foo *> > barFooVector
这将作为100个bar to Foo的反向映射。
为确保您不会在指针内纠结,使用std::shared_ptr
而不是裸指针更安全
std::vector<std::shared_ptr<Foo>> fooVector; //contains some 100 elements
std::vector<std::shared_ptr<Bar>> barVector; //contains some 10,000 elements
std::vector<std::pair<std::shared_ptr<Bar>, std::shared_ptr<Foo>> > barFooVector
std::vector<std::pair<std::shared_ptr<Foo>, std::shared_ptr<Bar>> > fooBarVector
在这些向量上创建辅助包装器也是高度可维护和可扩展的