简体   繁体   English

如何允许访问向量是类成员的向量元素?

[英]How to allow access to a vector elements where the vector is a class member?

I'm having a problem encapsulating a vector.我在封装向量时遇到问题。 This is with pre C++ 11 code.这是使用 C++ 11 之前的代码。

I have a class, let's call it A, that has a vector of objects as a member variable.我有一个类,我们称之为 A,它有一个对象向量作为成员变量。 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.我不想让 A 类的客户直接访问 vector。但是作为第一次尝试,我暴露了 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.我的代码的某些部分必须创建 A 类向量并遍历所有这些向量。 When I need to access all the elements of m_connectionList I end up with ugly looking code.当我需要访问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++)
    {
    }
}

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.我正在考虑为 A 类实现operator[]size()并转发来自 m_connectionList 的值,但这对我来说似乎并不干净。

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:使用 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;
}

If you ever switch to C++11, you can use range-for loops:如果您切换到 C++11,则可以使用range-for循环:

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.顺便说一句,当您将来能够切换到 C++11 时,这是否可以用于 ranged for 循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM