如何在 C++ 中以最佳方式遍历 class 成员向量的元素?

How to loop through a class member vector's elements in the best way in C++?

我有一个 class A 和一个成员 vector<class B>。我想以一种干净的方式从 class A 外部循环遍历 vector。我需要使用它的 public 函数对 B 进行操作。

为此,我想到了一个函数 int get_next_element(B * in_B),如果我已正确加载下一个元素,我可以在其中 return 0,否则 -1。

我想通过使用 iterator 来实现这一点,但我发现了两个问题。首先,我找不到将 iterator 转换为 pointer 的巧妙方法(似乎我可以像 pointer 一样使用 iterator,但我不确定这是一个好的解决方案)。其次,我需要检查我的 iterator 是否引用了一个值,并且由于最接近 "null iterator" 的是 .end() 元素,所以我不知道我会怎么做初始化它。如果我初始化它(空)并有引用 .end(),如果我向它添加一些东西,它不会引用任何可比较的东西。

我可以有一个额外的 int 来跟踪我在哪个元素,但是我必须管理那个 int 每当我添加元素等时

我考虑过将迭代代码放在 class A 之外,但我可能需要在循环期间更改或访问单个元素,这样会形成一个 complex/big 迭代块。

我如何以干净的方式解决这个问题(例如 int get_next_element(B * in_b))?

编辑: 这是一些代码: Header:

class B {
  public:
    B();
    void set_size(int in_size);
    int get_size();
  protected:
    int mSize;
};

class A {
  public:
    A();
    void add_B(B in_B);
    int get_next_element(B * in_B);
  protected:
    std::vector<B> mObjects;
};

cpp 文件:

B::B() {
  // Stuff
}
void B::set_size(int in_size) {
  mSize = in_size;
}
int B::get_size() {
  return mSize;
}

A::A() {
  // Stuff
}
void A::add_B(B in_B) {
  mObjects.push_back(in_B);
}
int A::get_next_element(B * in_B) {
  // ToDo : handle elements
}

和主要的:

int main() {
  A test_a;
  for (int i = 0; i < 5; i++) {
    B tmp_b;
    tmp_b.set_size(i);
    test_a.add_B(tmp_b);
  }
  B iterator_b;
  while (0 == get_next_element(& iterator_b)) {
    if (iterator_b.get_size > 2) {
      B tmp_b;
      tmp_b.set_size(iterator_b.get_size - 2);
      test_a.add_B(tmp_b);
      iterator_b.set_size(2);
    }
  }
}

所以,基本上 A 拥有一堆 B 并且可以帮助主要遍历它们并且(在这个例子中)将它们切成更小的部分,同时在代码中没有太多代码main。有很多 dimensions/ways 这将被完成,这就是为什么我想 "hide" 尽可能多地 A.

中的代码的部分原因

(这个有点简化,像B可能要有内部关系,但基本上就是这个意思)

考虑使用 range-base for loop (C++1x)。

class A {
  private:
    std::vector<class B> vec;
  public:
    std::vector<class B>& get_vec() { return vec; }
};

A a_instance;
for (B &b : a_instance.get_vec()) {
    b.print();
    std::cout <<  "b = " <<  b << std::endl;
    std::cout << "&b = " << &b << std::endl;
}

不幸的是,这不允许向前看,除非您自己跟踪索引。

这就是我的意思...

#include <iostream>
#include <vector>

class B {
public:
    B(int in) :mSize(in) {}
    size_t mSize;
    void set_size(int in_size) {    mSize = in_size;}
    int get_size() {return mSize;}
};

class A {
    using container = std::vector<B>;
    using iterator = container::iterator;
    container mObjects;
public:
    void add_B(B in_B) { mObjects.push_back(in_B); }
    iterator begin() { return mObjects.begin(); }
    iterator end() { return mObjects.end(); }
};


int main() {
    A test_a;
    for (int i = 0; i < 5; i++) {
        test_a.add_B(B(i));
    }
    for( auto& item : test_a)
        if (item.get_size() > 2) {
            B tmp_b(item.get_size() - 2);
            item.set_size(2);
            test_a.add_B(tmp_b);
            break;//if using a vector, must break as vector can change/reallocate on 'add_B()'
    }
}