Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Rename" member variables in derived classes

The question may seem a little bit weird but I'll try to contestualize a little bit the use case.

Suppose you have a generic implementation of a two-dimensional (Cartesian) field with dimensions dim1 and dim2, coordinates c1 and c2.

struct Field2D {
  struct size_type {
     size_t dim1,dim2;
  };
  struct coordinates {
     size_t c1,c2;
  }
Field2D(size_type const & siz) : size_(siz), data(size_.dim1*size_.dim2) {}
double get(coordinates const & coords) {
  return data_[coords.c1*size_.dim2 + coords.c2];
}
//Other methods
private:
  size_type size_;
  vector<double> data_;
};

You want to inherit from this class but you want to be more explicit about the nature of the coordinates. For example, a field PositionVersusTime whose coordinates are "x" and "t" and dimensions "nx" and "nt", whose usage I'd like to be

int main(){
   PositionVersusTime::size_type siz;
   siz.nx = 5;
   siz.nt = 2;
   PositionVersusTime myField(siz);
   PositionVersusTime::coordinates coords;
   coords.x = 2;
   coords.t = 0;
   auto out = myField.get(coords);
   return 0;
}

The reason I want to do this is that the ordering may change depending on the field (for example a TimeVersusPosition) and sometimes "forgotten" by the user. Is there a way to obtain a similar behavior? or should I simply go with getters (e.g., coords.x() = 2) ?

like image 355
Teloze Avatar asked Jul 24 '19 19:07

Teloze


People also ask

Do derived classes inherit members?

The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.

Can a derived class access public members?

A class can always access its own (non-inherited) members. The public accesses the members of a class based on the access specifiers of the class it is accessing. A derived class accesses inherited members based on the access specifier inherited from the parent class.

Can a derived class redefine a base class function?

It uses whatever access specifier it is defined under in the derived class. Therefore, a function that is defined as private in the base class can be redefined as public in the derived class, or vice-versa!

Can derived class have its own features?

The child or derived class inherits all the features of its parent or base class, and is free to add features of its own.


2 Answers

No. You cannot "rename" a base class member in a derived class. That's simply not something the language allows.

A variable gets its name when it is declared and that is then its name forever. You can create aliases (references) to it if you like or you can have functions by whatever name that changes it, but the fundamental name of a variable is set in stone at declaration time.

like image 104
Jesper Juhl Avatar answered Sep 19 '22 11:09

Jesper Juhl


Combining others solutions and using inheritance and reference data members, here is my solution.

Notice slight changes to the Field2D variable types.

struct size_type{
    size_t dim1, dim2;
};

struct PositionVsTime_size_type : public size_type{
    size_t& nx = dim1;
    size_t& nt = dim2;
};

struct coordinates {
    size_t c1,c2;
};

struct PositionVsTime_coordinates : public coordinates{
    size_t& x = c1;
    size_t& t = c2;
};

struct Field2D {
    Field2D(size_type& siz) : size_(siz), data_(size_.dim1*size_.dim2) {}
    double get(coordinates& coords) {
        return data_[coords.c1*size_.dim2 + coords.c2];
    }
    Field2D& set(coordinates& coords, double val){
        data_[coords.c1*size_.dim2 + coords.c2] = val;
        return *this;
    }
    private:
    size_type& size_;
    vector<double> data_;
};

struct PositionVersusTime : public Field2D {
    PositionVersusTime(size_type& siz) : Field2D(siz) {}
};

int main(){
   PositionVsTime_size_type siz;
   siz.nx = 5;
   siz.nt = 2;
   PositionVersusTime myField(siz);
   PositionVsTime_coordinates coords;
   coords.x = 2;
   coords.t = 0;
   myField.set(coords, 5);
   auto out = myField.get(coords);
   cout << out << endl; // will print 5
   return 0;
}
like image 35
Daniel Avatar answered Sep 20 '22 11:09

Daniel