我有一个类,并且有几种方法可以遍历它。例如,您可以迭代查看其中的所有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();
};
然后
A_view& get_C_view(const myClass& c) {
return *reinterpret_cast<B_view*>(&c);
}
B_view& get_B_view(const myClass& c) {
return *reinterpret_cast<B_view*>(&c);
}
C_view& get_C_view(const myClass& c) {
return *static_cast<C_view*>(&c);
}
我希望能够做到这样使用它
myClass inst;
for (auto& c : get_C_view(inst))
//stuff
for (auto& b : get_B_view(inst))
//stuff
和
auto& bview = get_b_view(inst);
std::transform(bview.begin(), bview.end(), bview.begin(), [](auto& x, auto& y) { /* smthing */ });
bview.myFunc();
或任何与<algorithm>
算法。如您所见,您还可以使用视图上父类中定义的函数。
所以,我将一个实例强制转换为从其派生的类型的引用,该类型仅添加函数,而不是数据,但实际上并不是这些类型之一。
可以吗? “OK”我的意思是
- 这是明确的,未定义的或未指定的行为?
- 如果没有明确定义,这是否会导致实践中的问题?
- 药草萨特会皱眉吗?
为什么不只有'A_begin','A_end'等方法?或者,如果您为每种类型设置单独的类,请将“A_view”设置为朋友类,而不是派生类。 –
@TaylorBrandstetter因为我的实际情况太多了。而且那些不能用于需要'begin' /'end'方法的东西,比如基于范围的。 – Jay
如果您只是简单地将'A_view'作为独立类而不是派生类(如下面的答案),那么您应该能够以完全相同的方式使用它,并且编写几乎相同数量的代码行。如果“c_begin()”的等价物是私有的,你只需要把它变成朋友。 –