I'm having a problem encapsulating a vector. This is with pre C++ 11 code.
I have a class, let's call it A, that has a vector of objects as a member variable. I don't want to give direct access to vector to the clients of class A. However as a first stab I exposed the vector.
class A
{
public:
struct ConnectionEntry
{
int portNumber;
...
}
std::vector<ConnectionEntry> m_connectionList;
private:
}
There are parts of my code where I have to create vectors of class A and iterate through all of them. When I need to access all the elements of m_connectionList
I end up with ugly looking code.
vector<A> vecOfA;
for (vector<A>::iterator it = vecOfA.begin; it != vecOfA.end(); it++)
{
for (vector<A::ConnectionEntry>::iterator conn = it->m_connectionList.begin();
conn != it->m_connectionList.end();
conn++)
{
}
}
I don't like that I have the vector exposed. I was thinking about implementing the operator[]
and size()
for class A and forwarding the values from m_connectionList but that doesn't seem clean to me.
Is there a standard way of solving this problem? Encapsulating the vector and only exposing certain parts without having to re-implement all the standard vector functions.
When using C++03, these are the possibilities:
#include <iostream>
#include <vector>
struct Foo {
struct Bar {
int value;
};
std::vector<Bar> bars;
};
int main() {
std::vector<Foo> foos;
for (unsigned int i = 0; i < foos.size(); ++i) {
for (unsigned int j = 0; j < foos[i].bars.size(); ++j) {
// do something
}
}
// or
typedef std::vector<Foo>::iterator FooIt;
typedef std::vector<Foo::Bar>::iterator BarIt;
for (FooIt foo = foos.begin(); foo != foos.end(); ++foo) {
for (BarIt bar = foo->bars.begin(); bar != foo->bars.end(); ++bar) {
// do something
}
}
return 0;
}
If you ever switch to C++11, you can use range-for
loops:
std::vector<Foo> foos;
for (auto const& it : foos) {
for (auto const& bars : it.bars) {
// do something
}
}
Personally, I would do the following:
class A
{
public:
struct ConnectionEntry
{
int portNumber;
...
}
typedef iterator typename std::vector<ConnectionEntry>::iterator;
typedef const_iterator typename std::vector<ConnectionEntry>::const_iterator;
// hope I got that one right, I am used to using
iterator begin() { return m_connectionList.begin(); }
iterator end() { return m_connectionList.end(); }
iterator cbegin() const { return m_connectionList.cbegin(); }
iterator cend() const { return m_connectionList.cend(); }
private:
std::vector<ConnectionEntry> m_connectionList;
}
And use it like this:
vector<A> vecOfA;
for (vector<A>::iterator it = vecOfA.begin; it != vecOfA.end(); it++)
{
for (A::iterator conn = it->begin(); conn != it->end(); conn++)
{
}
}
Btw will this be ready for ranged for loops when you are able to switch to C++11 in the future.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.