C++ “提供可编辑的”;“意见”;通过将父类强制转换为对子类的引用
我有一个类,有几种方法可以迭代它。例如,您可以迭代查看其中的所有C++ “提供可编辑的”;“意见”;通过将父类强制转换为对子类的引用,c++,C++,我有一个类,有几种方法可以迭代它。例如,您可以迭代查看其中的所有A、B、或C。该类没有虚拟函数 我希望这些有一个很好的界面。我想知道下面是否给出了未定义或未指定的行为,或者是否可以这样做 我正在考虑制作这个类的三个派生类: // can look at this in three ways struct myClass { void myFunc(); }; struct A_view : public myClass { A_iterator begin(); }; str
A
、B
、或C
。该类没有虚拟函数
我希望这些有一个很好的界面。我想知道下面是否给出了未定义或未指定的行为,或者是否可以这样做
我正在考虑制作这个类的三个派生类:
// can look at this in three ways
struct myClass {
void myFunc();
};
struct A_view : public myClass {
A_iterator begin();
};
struct B_view : public myClass {
B_iterator begin();
};
struct C_view : public myClass {
C_iterator begin();
};
然后
及
或者使用
中的算法。如您所见,您还可以在视图上使用父类中定义的函数
因此,我将一个实例强制转换为对一个类型的引用,该类型是从它派生的,它只添加函数,不添加数据,但实际上它不是这些类型中的一种
这样行吗?我的意思是“好”
在这种情况下,继承不是正确的工具,原因有多种,首先是您不能将对象强制转换为它不是的类型,但更普遍的是,因为继承是语言中第二高的耦合关系,应该谨慎使用(即在需要时,而不仅仅是因为) 您可以创建包含对您的类型的引用的精简包装类型,并将其开始/结束函数映射到组件上的适当视图:
struct C_view {
MyClass &obj;
C_view(MyClass& obj) : obj(obj) {}
C_iterator begin() {
return obj.c_begin();
}
C_iterator end() {
return obj.c_end();
}
};
然后用户代码变成:
for (auto &c : C_view(inst)) {
...
}
在这种情况下,继承不是正确的工具,原因有多种,首先是您不能将对象强制转换为它不是的类型,但更普遍的是,因为继承是语言中第二高的耦合关系,应该谨慎使用(即在需要时,而不仅仅是因为) 您可以创建包含对您的类型的引用的精简包装类型,并将其开始/结束函数映射到组件上的适当视图:
struct C_view {
MyClass &obj;
C_view(MyClass& obj) : obj(obj) {}
C_iterator begin() {
return obj.c_begin();
}
C_iterator end() {
return obj.c_end();
}
};
然后用户代码变成:
for (auto &c : C_view(inst)) {
...
}
在这种情况下,继承不是正确的工具,原因有多种,首先是您不能将对象强制转换为它不是的类型,但更普遍的是,因为继承是语言中第二高的耦合关系,应该谨慎使用(即在需要时,而不仅仅是因为) 您可以创建包含对您的类型的引用的精简包装类型,并将其开始/结束函数映射到组件上的适当视图:
struct C_view {
MyClass &obj;
C_view(MyClass& obj) : obj(obj) {}
C_iterator begin() {
return obj.c_begin();
}
C_iterator end() {
return obj.c_end();
}
};
然后用户代码变成:
for (auto &c : C_view(inst)) {
...
}
在这种情况下,继承不是正确的工具,原因有多种,首先是您不能将对象强制转换为它不是的类型,但更普遍的是,因为继承是语言中第二高的耦合关系,应该谨慎使用(即在需要时,而不仅仅是因为) 您可以创建包含对您的类型的引用的精简包装类型,并将其开始/结束函数映射到组件上的适当视图:
struct C_view {
MyClass &obj;
C_view(MyClass& obj) : obj(obj) {}
C_iterator begin() {
return obj.c_begin();
}
C_iterator end() {
return obj.c_end();
}
};
然后用户代码变成:
for (auto &c : C_view(inst)) {
...
}
为什么不使用
A_开始
,A_结束
等方法呢?或者,如果设置为每种类型都有单独的类,请将A_视图
设置为友元类,而不是派生类。@TaylorBrandstetter,因为在我的实际情况中有太多的类。同样,那些不适用于需要begin
/end
方法的东西,比如基于范围的for。如果您只是将A_视图
作为一个独立类而不是派生类(如下面的答案所示),您应该能够以完全相同的方式使用它,并编写几乎相同数量的代码行。如果等价的c\u begin()
是私有的,你只需要把它变成朋友。为什么不干脆用a\u begin
、a\u end
等方法呢?或者,如果设置为每种类型都有单独的类,请将A_视图
设置为友元类,而不是派生类。@TaylorBrandstetter,因为在我的实际情况中有太多的类。同样,那些不适用于需要begin
/end
方法的东西,比如基于范围的for。如果您只是将A_视图
作为一个独立类而不是派生类(如下面的答案所示),您应该能够以完全相同的方式使用它,并编写几乎相同数量的代码行。如果等价的c\u begin()
是私有的,你只需要把它变成朋友。为什么不干脆用a\u begin
、a\u end
等方法呢?或者,如果设置为每种类型都有单独的类,请将A_视图
设置为友元类,而不是派生类。@TaylorBrandstetter,因为在我的实际情况中有太多的类。同样,那些不适用于需要begin
/end
方法的东西,比如基于范围的for。如果您只是将A_视图
作为一个独立类而不是派生类(如下面的答案所示),您应该能够以完全相同的方式使用它,并编写几乎相同数量的代码行。如果等价的c\u begin()
是私有的,你只需要把它变成朋友。为什么不干脆用a\u begin
、a\u end
等方法呢?或者,如果设置为每种类型都有单独的类,请将A_视图
设置为友元类,而不是派生类。@TaylorBrandstetter,因为在我的实际情况中有太多的类。同样,那些不适用于需要begin
/end
方法的东西,比如基于范围的for。如果您只是将A_视图
作为一个独立类而不是派生类(如下面的答案所示),您应该能够以完全相同的方式使用它,并编写几乎相同数量的代码行。如果等价的c_begin()
是私有的,你只需要把它当作朋友。但是,你必须有一种更笨拙的方式来访问被包装的东西上的函数。那么