Как разрешить доступ к элементам вектора, где вектор является членом класса? - PullRequest
0 голосов
/ 31 января 2020

У меня проблема с инкапсуляцией вектора. Это с кодом до C ++ 11.

У меня есть класс, назовем его A, в котором в качестве переменной-члена есть вектор объектов. Я не хочу давать прямой доступ к вектору клиентам класса А. Однако в качестве первого удара я раскрыл вектор.

class A
{
public:

    struct ConnectionEntry
    {
        int portNumber;
        ...
    }

    std::vector<ConnectionEntry> m_connectionList;
private:
}

В моем коде есть части, где мне нужно создавать векторы класс А и перебрать все из них. Когда мне нужно получить доступ ко всем элементам m_connectionList, я получаю уродливый код.

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++)
    {
    }
}

Мне не нравится, что у меня выставлен вектор. Я думал о реализации operator[] и size() для класса A и пересылке значений из m_connectionList, но мне это не кажется чистым.

Существует ли стандартный способ решения этой проблемы? Инкапсуляция вектора и раскрытие только определенных частей без необходимости повторной реализации всех стандартных функций вектора.

Ответы [ 2 ]

1 голос
/ 31 января 2020

Лично я бы сделал следующее:

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;
}

И использовал бы это так:

vector<A> vecOfA;

for (vector<A>::iterator it = vecOfA.begin; it != vecOfA.end(); it++)
{
  for (A::iterator conn = it->begin(); conn != it->end(); conn++)
  {
  }
}

Кстати, это будет готово для дальней связи, когда вы сможете переключаться на C ++ 11 в будущем.

1 голос
/ 31 января 2020

При использовании C ++ 03 это следующие возможности:

#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;
}

Если вы когда-либо переключитесь на C ++ 11, вы можете использовать range-for циклы:

std::vector<Foo> foos;

for (auto const& it : foos) {
    for (auto const& bars : it.bars) {
        // do something
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...