可以查询所有继承类的同名方法吗?

Can you query same named methods of all inherited classes?

本文关键字:方法 查询 继承      更新时间:2023-10-16

我正在研究一个基于节点的结构来定义一个生物。身体的每个部位都有"插座",你可以把东西放在那里,比如四肢、爪子或其他什么东西。为了方便将来的开发,如果我能把部分类拼凑在一起,并让它们的方法一起工作,那就太好了。例如:

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
    }
}

这有可能吗?

否则我当然可以手动写出每个传单类上的套接字,但是当我对抽象更具体时,这可能会变得非常繁琐。

也许这样的东西对你有用?

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;
    }
}

没有办法枚举类的所有直接基(据我所知,尽管他们可能正在为以后的c++版本开发一个)。除此之外,库皮亚科斯的回答应该还不错。如果您需要多次执行此类操作,并且需要合并大量基类,则可以进行一些模板元编程,以获得更简洁的快捷方式:

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的预期用途是什么:根据您要完成的任务,可能有更好的方法来构建代码,而不涉及太多有问题的OOP