派生类中的“重命名”成员变量

时间:2019-07-24 19:48:54

标签: c++ member-variables

这个问题似乎有点怪异,但我会尝试对用例进行一点争辩。

假设您具有二维(笛卡尔)字段的通用实现,其维度为dim1和dim2,坐标为c1和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_;
};

您想从此类继承,但您想更明确地了解坐标的性质。例如,一个字段PositionVersusTime,其坐标为“ x”和“ t”,尺寸为“ nx”和“ nt”,我希望将其使用

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;
}

我要执行此操作的原因是,排序可能会根据字段(例如TimeVersusPosition)而改变,有时会被用户“遗忘”。有没有办法获得类似的行为?还是我应该简单地使用吸气剂(例如,coords.x()= 2)?

4 个答案:

答案 0 :(得分:5)

不。您不能“重命名”派生类中的基类成员。这根本不是语言所允许的。

变量在声明时获得其名称,然后永远是其名称。您可以根据需要创建别名(引用),也可以使用可以更改其名称的函数来命名,但是变量的基本名称在声明时设置为石头。

答案 1 :(得分:2)

您不能在子类中重命名变量,但只需做一些工作,就可以编写main代码了。

我首先要在coordinates范围内创建自己的自定义size_typePositionVersusTime::。然后在get中重写构造函数和PositionVersusTime函数以采用这些新结构。

因此您的PositionVersusTime结构看起来像:

struct PositionVersusTime : public Field2D {
    struct size_type { size_t nx, nt; };
    struct coordinates { size_t x, t; };
    PositionVersusTime(size_type const & siz) : Field2D({siz.nx, siz.nt}) { }
    double get(coordinates const & coords) { return Field2D::get({coords.x, coords.t}); }
};

然后,您发布的主要代码将按预期工作:

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;
}

在此处查看其工作原理:ideone

答案 2 :(得分:2)

结合其他解决方案并使用继承和引用数据成员,这是我的解决方案。

请注意,Field2D变量类型略有更改。

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;
}

答案 3 :(得分:0)

您不能在派生类中重命名,但可以使用对派生类中基本成员的引用

size_t& x = coordinates::c1;

但是,使用引用会阻止重新分配,因为无法重新分配参考,并且在分配时必须找到解决方法。