连接两个对象的明智方法

时间:2015-04-14 10:04:08

标签: c++ pointers linked-list

我有两个对象向量:

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的东西,但最终仍然存在相同的迭代问题。

4 个答案:

答案 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

在这些向量上创建辅助包装器也是高度可维护和可扩展的

相关问题