按名称调用父级中的子类方法

Call child class method in parent by name

本文关键字:类方法 调用      更新时间:2023-10-16

如何实现invoke函数?

class Args {};
class NoSuchMethod {};
class Base {
        public:
                Args invoke(std::string name, Args a) {
                        //get method and call it or
                        //throw NoSuchMethod()
                }
};
class One: public Base {
                int q;
        public:
                One(int q_): q(q_) {};
                Args test(Args a) {
                        printf("One::test() -> q = %d", q);
                };
};
class Two: public Base {
                std::string s;
        public:
                Two(std::string s_): s(s_) {};
                Args test2(Args a) {
                        printf("Two::test2() -> t = %s", s.c_str());
                };
};
std::vector<Base*> objs = {new One(123), new One(321), new Two("ha"), new One(0)};
int main() {
        objs[0]->invoke("test", Args());
        objs[1]->invoke("test", Args());
        objs[2]->invoke("test2", Args());
        objs[3]->invoke("test", Args());
}

不能直接从字符串调用方法。 如果基方法无权访问父方法的类型,则也无法从基方法调用父方法。

实现此目的的一种方法是设置一个包含所需功能的映射。

类似的东西(代码未编译,但它应该给你一个想法(:

    class Base {
            public:
                    Args invoke(std::string name, Args a) {
                            auto foundMethod = methods_.find(name);
                            if (foundMethod == methods_.end())
                            {
                                    throw NoSuchMethod();
                            }
                            (*foundMethod)(a);
                    }
            protected:
                    std::map<std::string, std::function<void(Args)>> methods_;
    };
    class One: public Base {
                    int q;
            public:
                    One(int q_): q(q_)
                    {
                            methods_["test"] = std::bind(&One::test, this, std::placeholders::_1);
                    };
                    Args test(Args a) {
                            printf("One::test() -> q = %d", q);
                    };
    };
    class Two: public Base {
                    std::string s;
            public:
                    Two(std::string s_): s(s_)
                    {
                            methods_["test2"] = std::bind(&Two::test, this, std::placeholders::_1);
                    };
                    Args test2(Args a) {
                            printf("Two::test2() -> t = %s", s.c_str());
                    };
    };