2

I am trying to create a 2D dynamic array where each row would correspond to the list of different data type. For this purpose I am using a vector of pointers, where each pointer would point to a 1D array of a certain type. To create a generic array, I created a template class which I derived from an abstract class, so that I can use the abstract class pointers in my array(12009314). Following is the code where I am trying to do this but the problem is since I don't have the array pointer in the abstract class, I am not able to access the array elements:

class abs_attribute{
    public:
        virtual void insertAttribute(abs_attribute* a){}
        virtual void print(){}
};
template <class T>
class attribute:public abs_attribute{
    public:
        T *data;
        int size;
        attribute(int s=3){
            size=s;
            data=new T[size];
        }
        void print(){
            for(int i=0;i<size;i++)
              cout<<data[i]<<" ";
            cout<<"\n";
        }
};
class Graph{
    private:
        vector<abs_attribute*>Attribute;
    public:
        Graph(){}
        void insertAttribute(abs_attribute* a){
            Attribute.push_back(a);
        }
        
        void printAttributes(){
            for(int i=0;i<Attribute.size();i++){
                for(int j=0;j<N;j++){
                   cout<<Attribute[i]->data[j]<<" ";//Not able to access data as it is not a member of abs_attribute
                }
            cout<<endl;
            }
        }
};
int main(){
    abs_attribute* age=new attribute<int>(N);
    age=new attribute<int>(N);
    for(int i=0;i<N;i++)
      static_cast<attribute<int>*>(age)->data[i]=rand()%50;
    
    age->print();
    Graph g;
    g.insertAttribute(age);
    g.printAttributes();
}

Is there any way to access data array inside the Graph class without knowing the template type of the derived class in advance? The main aim of this entire activity is to have an multiple arrays of different data types in my class. Since I cannot dynamically add data members to a class, I resorted to a vector where I'll keep pushing the array pointers, but this method became complicated due the requirement of the array elements being generic.

Community
  • 1
  • 1
ad6131
  • 21
  • 1
  • Arrays are generally intended for buffers of uniform data. Your top level array is not a buffer of uniform data; its elements are arrays of distinct types. So we have a mismatch of abstraction to problem. Is there a specific strong reason you want to ram this square peg into this round hole? I mean it can be done, but it probably shouldn't be done. The key question to ask is "what operations do I want to uniformly apply to the non-uniform types". Also, why fixed attributes are a problem. Don't get me wrong; I can and do write that kind of code. But I want to check first. – Yakk - Adam Nevraumont Mar 10 '18 at 20:53
  • The operations mainly include filtering. Let's say I have 10 nodes in a linked list representing different versions of a product. Their properties still remain the same, for example all the versions of a Car will have always have attributes like mileage, model number, fuel capacity, etc. Now I want to make a query to find out the number of versions with a fuel capacity greater that X and mileage greater than Y. This would involve traversing through all these arrays and capturing the ones satisfying my search query. This is precisely what I am trying to model here by writing this code. – ad6131 Mar 10 '18 at 21:31
  • But the the actual filter operation on mileage aren't going to apply to fuel economy or model number. And if all the version of Car have the same attributes, why isn't that in your type system? – Yakk - Adam Nevraumont Mar 10 '18 at 21:48
  • I am not sure if I understand your comment clearly. Yes, the filter operation on one array won't apply on the other array, but what are you trying to get at here. Is there a better alternative due to this fact? Regarding the second question, Car was just used as an example. The number of attributes and their types are not fixed for my problem: it can be a person, a truck or a semiconductor chip as well, each having their own group of attributes and types. So I cannot use a fixed set here. – ad6131 Mar 10 '18 at 22:07
  • So you *need* to be able to dynamically change the kinds of data stored without recompiling any code? Have you considered using a database? And do you also need to be able to change the operations you perform on the data without recompiling? In most paradigms if two things have different kinds of operations you can perform on them, they are things of *different type*. Arrays store things of the same type. By the way, by "2d array" are you thinking "a grid, like a spreadsheet"? – Yakk - Adam Nevraumont Mar 10 '18 at 22:14
  • There are lot of little things in your code that make me think you are just starting C++; the route you seem to want to go down is possible, but it is madness and fighting against the C++ type system. Your requirement are as vague as smoke, and any solution will vary massively based on what your actual requirements are. I advise you to reconsider your design and try a different approach. – Yakk - Adam Nevraumont Mar 10 '18 at 22:16
  • I just said 2D array since I am storing a list of pointers to one dimensional arrays. The main requirement is to keep adding arrays of different data types to my node and solve the queries. – ad6131 Mar 10 '18 at 22:47
  • Repeating yourself doesn't help, I understand what you said, I just find it deficient. My advice: Solve the problem in python or another language with a different type system. It can be solved in C++, but at the level of vagueness of your requirements the solution would look like "reimplement python". With very solid and flexible requirements, and a more experience programmer, it can be solved in C++, but none of these are in evidence. – Yakk - Adam Nevraumont Mar 10 '18 at 23:05

1 Answers1

0

You cannot magically do it. The object type has to be passed/known/used somehow.

In your main(), you have this line:

static_cast<attribute<int>*>(age)->data[i]=rand()%50;

See how you had to static_cast in order to access the data? It's the same thing.

  • I understand but is there some other approach to solve this problem then, i.e. storing a dynamic list of arrays, each having a different data type? – ad6131 Mar 10 '18 at 21:20