我正在开发一个基于节点的结构来定义一个生物。每个身体部位都可以有"插座"你可以把东西放在四肢或爪子等等。为了简化未来的发展,如果我可以将来自部分类的类拼凑在一起并使它们的方法协同工作,那将是一件好事。例如:
struct Generic {
vector<Generic*> GetSockets() {return vector<Generic*>();}
}
typedef Generic* GenSock;
struct Bipedal {
GenSock LeftLeg;
GenSock RightLeg;
vector<Generic*> GetSockets() {
vector<Generic*> ret;
ret.push_back(RightLeg);
ret.push_back(LeftLeg);
return ret;
}
}
struct TripleHeaded {
GenSock Head1;
GenSock Head2;
GenSock Head3;
vector<Generic*> GetSockets() {
vector<Generic*> ret;
ret.push_back(Head1);
ret.push_back(Head2);
ret.push_back(Head3);
return ret;
}
}
struct CrazyAlienTorso : Generic, Bipedal, Tripleheaded {
vector<Generic*> GetSockets() {
somehow call getsockets from all inherited classes and combine the vector for a single output
}
}
那可能吗?
否则我当然可以手动写出每个传单类的套接字,但随着我对抽象的更具体,这可能会变得非常繁琐。
答案 0 :(得分:1)
这样的事情对你有用吗?
struct CrazyAlienTorso : Generic, Bipedal, Tripleheaded {
vector<Generic*> GetSockets() {
vector<Generic*> v1 = Bipedal::GetSockets();
vector<Generic*> v2 = TripleHeaded::GetSockets();
v1.insert(v1.end(), v2.begin(), v2.end());
return v1;
}
}
答案 1 :(得分:1)
根据我所知,虽然他们可能正在为一个更高版本的C ++工作,但是没有办法枚举一个类的所有直接基础。除此之外,Kupiakos&#39;答案应该运作良好。如果您需要多次执行此类操作并且需要合并大量基类,则可以执行一些模板元编程以获得更简洁的快捷方式:
template <typename Base, typename... OtherBases>
struct socket_collector {
template <typename Derived>
static void add_sockets(Derived* obj, vector<Generic*>& sockets) {
socket_collector<OtherBases...>::add_sockets(obj, sockets);
auto new_sockets = static_cast<Base*>(obj)->GetSockets();
sockets.insert(end(sockets), begin(new_sockets), end(new_sockets));
}
};
template <typename Base> struct socket_collector<Base> {
template <typename Derived>
static void add_sockets(Derived* obj, vector<Generic*>& sockets) {
auto new_sockets = static_cast<Base*>(obj)->GetSockets();
sockets.insert(end(sockets), begin(new_sockets), end(new_sockets));
}
};
template <typename... Bases, typename Derived>
vector<Generic*> collect_sockets(Derived* obj) {
vector<Generic*> sockets;
socket_collector<Bases...>::add_sockets(obj, sockets);
return sockets;
}
//...
vector<Generic*> CrazyAlienTorso::GetSockets() {
return collect_sockets<Generic, Bipedal, TripleHeaded>(this);
}
当然,主要的问题是GetSockets
的预期用途是什么:根据您尝试完成的任务,可能有更好的方法来构建没有&#39的代码; t涉及尽可能多的问题OOP。