0

I have the following class containing simple member variables and a basic constructor:

struct SimpleStruct {
    SimpleStruct() = default;
    SimpleStruct(const int& a, const int &b, 
                 const double& c, const double& d, const double& e) : 
             A(a), B(b), C(c), D(d), E(e) {}
    
    int A, B;
    double C, D, E;
    // etc.. more properties could be added or removed to this class
};

I want to consider collections of SimpleStruct and so I decide to make a wrapper class. There are two basic options I can see:

class WrapperOne {
    public:
        Wrapper(const size_t& sz) { 
            SS.resize(sz); 
            nElements = 0;
        }

        void Push(const SimpleStruct& ss) { SS[nElements++] = ss; }

        std::vector<int> getA() const { 
            std::vector<int> result(SS.size());
            for (size_t i = 0; i < SS.size(); ++i) 
                result[i] = SS[i].A;
            return result;
        }
        // std::vector<int> getB() ... etc. for the remaining SimpleStruct member variables 
    private:
        std::vector<SimpleStruct> SS;
        size_t nElements;
};

or

class WrapperTwo {
    public: 
        WrapperTwo(const size_t& sz) {
            As.resize(sz);
            Bs.resize(sz);
            Cs.resize(sz);
            // etc.
            nElements = 0;
        }

        void Push(const SimpleStruct& SS) {
             As[nElements] = SS.A;
             Bs[nElements] = SS.B;
             Cs[nElements] = SS.C;
             // etc
             nElements++;
        }

        std::vector<int> getA() const { return As; }
        // etc.
    
    private:
        std::vector<int> As;
        std::vector<int> Bs;
        std::vector<double> Cs;
        size_t nElements;
};

WrapperOne is much easier to maintain if the members of SimpleStruct are added or removed. However, suppose we want to consider a large collection of SimpleStructs:

// ... 
WrapperOne SSCollection1(10000000);
WrapperTwo SSCollection2(10000000);
// ...

If both classes are fully implemented, they ought to require the same amount of memory (?). But suppose we don't need to look at all A, B, C, D, E and just need A and B for instance. Then in WrapperTwo we simply just avoid adding vectors for C,D,E and save memory.

Is there any way to define at run time a "subset" of the SimpleStruct class which can be used by WrapperOne? Or do I need to make WrapperOne a template class and then define a bunch of SimpleStruct variants which specify different combinations of member variables I might want to collect? Or do I perhaps stick with WrapperTwo and continually be commenting in/out lines of code depending on my use cases.

algae
  • 407
  • 4
  • 15
  • There's no need for a wrapper in case one. std::vector already contains its size, has proper constructor, push etc. methods, – Bartosz Bosowiec Sep 04 '20 at 04:30
  • What do you mean? – algae Sep 04 '20 at 04:49
  • You may want to do some research on Data Oriented Design. – Bob__ Sep 04 '20 at 08:34
  • @Bob__ Thanks. [this](https://stackoverflow.com/questions/1641580/what-is-data-oriented-design) post was quite revealing. In effect, my `WrapperTwo` class would become the `SimpleStruct` class and make any business of 'wrapping' redundant. I don't see how it reduces memory usage though. – algae Sep 06 '20 at 00:12

0 Answers0