"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_;
};
您希望从此类继承,但希望更明确地说明坐标的性质。例如,一个字段 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(而变化,有时被用户"遗忘"。有没有办法获得类似的行为?或者我应该简单地使用 getter(例如,coords.x(( = 2(?
No.不能"重命名"派生类中的基类成员。这根本不是语言所允许的。
变量在声明时获得其名称,然后永远是其名称。如果您愿意,您可以创建对它的别名(引用(,或者您可以使用任何名称来更改它的函数,但是变量的基本名称在声明时是一成不变的。
组合其他解决方案并使用继承和引用数据成员,这是我的解决方案。
请注意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;
}
您不能重命名子类中的变量,但只需稍加努力,就绝对可以编写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。
不能在派生类中重命名,但可以使用对派生类中基成员的引用
size_t& x = coordinates::c1;
但是,使用引用将阻止重新分配,因为无法重新分配引用,并且您必须在分配时找到解决方法。
正如此处注释中所述,在派生类中使用引用的解决方案可能会有问题,因为它引入了创建悬空引用的可能性.
你想避免这种情况。
而不是做:
struct size_type{
size_t dim1;
};
struct PositionVsTime_size_type : public size_type{
size_t& nx = dim1;
};
只需做:
#define nx dim1
struct size_type{
size_t dim1;
};
struct PositionVsTime_size_type : public size_type{
};
现在,编译器将 dim1 替换为源文件中每次出现的令牌 nx。
如果 nx 不形成标记,则不会替换 - 出现在注释、字符串中或作为较长标识符的一部分。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 将包含C样式数组的对象初始化为成员变量(C++)
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在循环中按顺序遍历成员变量
- c++类声明时,相同的例程,不同的成员变量类型
- 如何从另一个文件继承私有成员变量和公共函数
- 在C++类中,是否必须初始化作为数组的成员变量
- 如何从子成员函数修改父公共成员变量
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 打印所有继承的类成员变量和方法
- 如何在复杂继承中访问静态成员变量
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 成员变量与函数概念检查