"Rename"派生中的成员变量类
"Rename" member variables in derived classes
这个问题可能看起来有点奇怪,但我会尝试对用例进行一些争论。
假设您有一个二维(笛卡尔)场的通用实现,其维度为 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_;
};
您想从此 class 继承,但您想更明确地了解坐标的性质。例如,坐标为 "x" 和 "t" 并且尺寸为 "nx" 和 "nt" 的字段 PositionVersusTime,我希望其用法为
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)而改变,有时 "forgotten" 由用户改变。有没有办法获得类似的行为?或者我应该简单地使用吸气剂(例如,coords.x() = 2)?
没有。您不能 "rename" 派生 class 中的基础 class 成员。这根本不是语言所允许的。
变量在声明时获得它的名字,然后永远是它的名字。如果你愿意,你可以为它创建别名(引用),或者你可以使用任何名称更改它的函数,但是变量的基本名称在声明时是固定的。
您不能在派生 class 中重命名,但您可以在派生 class
中使用对基成员的引用
size_t& x = coordinates::c1;
但是,使用引用会阻止重新分配,因为无法重新分配引用,并且您必须在分配的情况下找到解决方法。
您不能 重命名 子变量 class,但只要稍加努力,就可以编写 main
代码。
我首先在 PositionVersusTime::
范围内自定义 coordinates
和 size_type
。然后覆盖 PositionVersusTime
中的构造函数和 get
函数以获取这些新结构。
因此您的 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
结合其他解决方案并使用继承和引用数据成员,这是我的解决方案。
请注意 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;
}
这个问题可能看起来有点奇怪,但我会尝试对用例进行一些争论。
假设您有一个二维(笛卡尔)场的通用实现,其维度为 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_;
};
您想从此 class 继承,但您想更明确地了解坐标的性质。例如,坐标为 "x" 和 "t" 并且尺寸为 "nx" 和 "nt" 的字段 PositionVersusTime,我希望其用法为
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)而改变,有时 "forgotten" 由用户改变。有没有办法获得类似的行为?或者我应该简单地使用吸气剂(例如,coords.x() = 2)?
没有。您不能 "rename" 派生 class 中的基础 class 成员。这根本不是语言所允许的。
变量在声明时获得它的名字,然后永远是它的名字。如果你愿意,你可以为它创建别名(引用),或者你可以使用任何名称更改它的函数,但是变量的基本名称在声明时是固定的。
您不能在派生 class 中重命名,但您可以在派生 class
中使用对基成员的引用size_t& x = coordinates::c1;
但是,使用引用会阻止重新分配,因为无法重新分配引用,并且您必须在分配的情况下找到解决方法。
您不能 重命名 子变量 class,但只要稍加努力,就可以编写 main
代码。
我首先在 PositionVersusTime::
范围内自定义 coordinates
和 size_type
。然后覆盖 PositionVersusTime
中的构造函数和 get
函数以获取这些新结构。
因此您的 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
结合其他解决方案并使用继承和引用数据成员,这是我的解决方案。
请注意 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;
}