如何在 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()'
}
}
我有一个 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()'
}
}