【问题标题】:How to allow access to a vector elements where the vector is a class member?如何允许访问向量是类成员的向量元素?
【发布时间】:2026-01-05 02:05:01
【问题描述】:

我在封装矢量时遇到问题。这是 C++ 11 之前的代码。

我有一个类,我们称它为 A,它有一个对象向量作为成员变量。我不想让 A 类的客户直接访问向量。但是,作为第一次尝试,我公开了向量。

class A
{
public:

    struct ConnectionEntry
    {
        int portNumber;
        ...
    }

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

在我的部分代码中,我必须创建类 A 的向量并遍历所有这些向量。当我需要访问 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++)
    {
    }
}

我不喜欢我暴露了矢量。我正在考虑为 A 类实现 operator[]size() 并转发来自 m_connectionList 的值,但这对我来说似乎并不干净。

有解决这个问题的标准方法吗?封装向量,只暴露特定部分,无需重新实现所有标准向量函数。

【问题讨论】:

  • 这是一个软件工程问题,可能更适合softwareengineering.stackexchange.com
  • 信息太少,无法提供帮助。我们不知道A::m_connectionList 包含什么,我们不知道A 的用户为什么关心这个向量以及为什么它需要访问整个向量。以及为什么A 存储这个向量而不是向量内容的实际用户。
  • 您的类A 是否具有类不变量,或者该类的用户可以以他们想要的任何方式修改成员吗?如果它具有不变量,则将 m_connectionList 设为私有,并让用户通过维护不变量的方法访问它。如果只是“一堆数据”,那么有公共成员变量就可以了。

标签: c++ oop vector stl


【解决方案1】:

就个人而言,我会做以下事情:

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 时,这将为远程 for 循环做好准备。

【讨论】:

    【解决方案2】:

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

    【讨论】: