0

如何获取向量内元素的位置,其中元素是类。有没有办法做到这一点?

示例代码:

class Object
{
  public:
    void Destroy()
    {
      // run some code to get remove self from vector
    }
}

在 main.cpp 中:

std::vector<Object> objects;
objects.push_back( <some instances of Object> );
// Some more code pushing back some more stuff

int n = 20;
objects.at(n).Destroy(); // Assuming I pushed back 20 items or more

所以我想我希望能够编写一个方法或作为类成员的东西,它将返回自身在向量内的位置......这可能吗?

编辑:

由于混乱,我应该更好地解释。

void Destroy(std::vector<Object>& container){
  container.erase( ?...? );
}

问题是,我怎样才能找到进行擦除的号码......?显然这是不可能的......我认为它可能不会......

4

4 回答 4

1

您可以使用std::find来查找元素vector(前提是您为 实现了比较运算符 ( ==) Object。但是,有两个大问题:

  1. 如果您需要在容器中查找元素,那么使用有序容器(例如std::mapor std::set(find operations in O(log(N))vsO(N)
  2. Object不应该是负责将自己从容器中移除的人。Object不应该知道或关心它在哪里,因为这会破坏封装。相反,容器的所有者应该关注这些任务。
于 2013-02-18T21:51:33.243 回答
1

对象可以这样擦除自己:

void Destroy(std::vector<Object>& container);
{
  container.erase(container.begin() + (this - &container[0]));
}

这将按您的预期工作,但它让我觉得设计非常糟糕。成员不应该知道他们的容器。他们应该(从他们自己的角度)存在于无法辨认的边缘。创造和毁灭应该留给它们的创造者。

于 2013-02-18T22:30:33.883 回答
0

向量中的对象不会自动知道它们在向量中的位置。

您可以为每个对象提供该信息,但要容易得多:从向量中删除对象。然后它的析构函数会自动运行。

然后这些对象也可以在其他容器中使用。


例子:

#include <algorithm>
#include <iostream>
#include <vector>

class object_t
{
private:
    int     id_;
public:
    int id() const { return id_; }

    ~object_t() {}
    explicit object_t( int const id ): id_( id ) {}
};

int main()
{
    using namespace std;
    vector<object_t> objects;

    for( int i = 0;  i <= 33;  ++i )
    {
        objects.emplace_back( i );
    }

    int const n = 20;
    objects.erase( objects.begin() + n );

    for( auto const& o : objects )
    {
        cout << o.id() << ' ';
    }
    cout << endl;
}
于 2013-02-18T21:48:29.043 回答
0

如果您需要销毁向量中的第 n 个项目,那么最简单的方法是从一开始就使用迭代器std::begin()并调用std::advance()来推进您想要的位置,例如:

std::vector<Object> objects;
const size_t n = 20;

auto erase_iter = std::advance(std::begin(objects), n);

objects.erase(erase_iter);

如果要在向量中查找项目的索引,则使用std::find获取迭代器并std::distance从头开始调用。

所以像:

Object object_to_find;
std::vector<Object> objects;

auto object_iter = std::find(std::begin(objects), std::end(objects), object_to_find);

const size_t n = std::distance(std::begin(objects), object_iter);

这确实意味着您需要为您的对象实现一个相等运算符。或者您可以尝试以下方法:

auto object_iter = std::find(std::begin(objects), std::end(objects), 
  [&object_to_find](const Object& object) -> bool { return &object_to_find == &object; });

尽管要使其正常工作,但 object_to_find 必须是实际列表中的一个,因为它只是比较地址。

于 2013-02-18T22:06:24.473 回答