我使用的语言是C ++,但问题与语言无关。我们说我们有
class State {};
enum StateTypes {MOVEMENT, AFFECTED_BY_SPELL, ..., ANGER, N,
CARRYING_WEAPON, CASTING_SPELL};
class Base {
array<stack<State*>, N> states; // MOVEMENT, AFFECTED_BY_SPELL, ..., ANGER
};
class Derived : public Base {
// array<stack<State*>, 2> states; // ??? CARRYING_WEAPON, CASTING_SPELL
};
和Derived比Base更有可能的状态。我需要一个数组中的所有状态堆栈,以便我可以遍历它们。但是,Derived具有Base所具有的所有可能状态以及Base所没有的一些状态,如上所述 - Derived将具有涉及携带武器或施放咒语的状态,这些状态不适用于基地。所以很自然,对于Derived,我想要一个长度为N + 2的状态堆栈数组(在本例中),但同时,我希望Derived继承&#39;状态&#39; Base中的数据成员并使用它。我如何设计这个,以便当Base迭代它的所有状态时它从MOVEMENT迭代到ANGER,而Derived从MOVEMENT迭代到CASTING_SPELL?是给Derived一个单独数组的唯一解决方案,N + 2&gt;陈述数据成员并完全忽略其Base ::状态?或者让Base拥有所有N + 2状态,即使其中一些状态类别在Base中没有任何意义(只有Derived可以携带武器或施放咒语)?必须有更好的方法。
这个问题实际上是一个更通用的问题:派生类如何具有基类容器数据成员的超集容器数据成员,除了将超集移到上面之外,两个容器上的所有操作都以相同的方式执行Base,或者只有在完全忽略Base的容器数据成员时才使用Derived的超集?是否有特殊模式来处理这个问题?
为Derived创建一个容器数据成员,它只包含Base的容器数据成员中没有的元素,然后让操作通过Bases&#39;容器,然后以某种方式继续进入Derived的容器???
class State {};
enum StateTypes {MOVEMENT, AFFECTED_BY_SPELL, ..., ANGER, N,
CARRYING_WEAPON, CASTING_SPELL};
struct Base {
array<stack<State*>, N> states; // MOVEMENT, AFFECTED_BY_SPELL, ..., ANGER
virtual void foo() {for (State* x : states) {foo_helper();} }
void foo_helper();
virtual const array<stack<State*>, N>& getStates() const {return states;}
};
struct Derived : public Base {
array<stack<State*>, 2> states; // CARRYING_WEAPON, CASTING_SPELL
virtual void foo() override {
const array<stack<State*>, N+2> allStates = Base::states + states merged;
for (State* x : allStates) {foo_helper();} // Good idea?
}
virtual const array<stack<State*>, N+2>& getStates() const override {
return Base::states + states merged; // won't work because of different return type
}
};
如果Derived有自己的派生类以及它们自己的唯一状态,那么同样的问题,等等......
答案 0 :(得分:1)
您无法封装Base类及其后代的状态管理。考虑永远不要直接引用状态容器并在内部管理状态。
毕竟,班级的用户只需知道每个堆栈的最后状态(如果我明白了)。
要抓住它们,请使用vector:
class Base {
vector<stack<State*>> states; // MOVEMENT, AFFECTED_BY_SPELL, ..., ANGER
public:
Base() {
states.reserve(N);
states.push_back(....)
}
vector<State*> getStates() const {
vector<State*> rv;
rv.reserve(N);
for(stack<State*> & stack: states) {
rv.push_back(stack.top());
}
return rv;
}
};
struct Derived : public Base {
Derived() {
states.reserve(N+2);
states.push_back(....)
}
}