我有一个类,有几种方法可以迭代它。例如,您可以迭代查看其中的所有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”我的意思是
答案 0 :(得分:3)
由于多种原因,继承不是在这种情况下使用的正确工具,第一个是你不能将对象强制转换为它不是的类型,但更普遍的是因为继承是第二个最高的耦合关系。语言,应谨慎使用(即需要时,不仅仅是因为)。
您可以创建包含对类型的引用的瘦包装类型,并将其开始/结束函数映射到组件上的相应视图:
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)) {
...
}