Search code examples
c++c++11encapsulation

Access private member vector of multiple objects in other class


I have two classes (A & B) with a similar structure, which both contain a vector of structs.

class A/B{
private: std::vector<DataStruct> vec_A/vec_B;
...
public:
...
}

To create/update an object of B, I have to combine the data from the vectors of multiple objects of class A (combining similar entries in the vector into one entry in the vector of object B and do data transformations in B).

How do I do this?

My thoughts were:

  • Making class B a friend of A. But I've heard, that making classes friends in C++ is only the last resort and should be avoided.
  • Writing a getVector() function in class A, which returns a reference to the Vector vec_A, so that class B can operate on the data. For me this seems to simply bypass the data encapsulation. What would be the advantage to setting the vector to public?
  • Writing a getVector() function in class A, which returns a copy of vec_A. But as vec_A is not that small, this seems to be inefficient (ok, only a few kB. Should work but in general...)
  • Write a function for class A, which does the calculation and creates an object of class B. Then concatenate multiple objects of B into one final object of B. However, this seems to be a lot of overhead to me.

Solution

  • Writing a getVector() function in class A, which returns a reference to the Vector vec_A, so that class B can operate on the data. For me this seems to simply bypass the data encapsulation. What would be the advantage to setting the vector to public?

    If B just needs to observe the content of vec_A, consider returning a const reference (const &):

    class A {
     ...
      public:
    
        // Give read-only access to vec_A
        const std::vector<DataStruct> & getVector() const {
            return vec_A;
        }
    };
    

    I prefer this solution to just making the vector data member public: with accessors (getter/setter) you have better control. For example you can implement a read-only access (like shown above). Or, if you want to provide a setter, you can also implement some checking on the input argument, etc.