如何自动化覆盖方法?

How to automatize overriding methods?

我想知道是否有任何棘手的方法可以以相同的方式覆盖所有 class 方法。例如,如何在大型 classes 中明智地实现复合模式?例如,当我得到这样的东西时:

        class Foo{
            virtual void work() = 0;
...
        };

        class FooLeaf : public Foo{
            virtual void work() override{}
...
        };

        class FooComposite : public Foo{
            std::vector<Foo *> foos;
            virtual void work() override{
                for (auto foo : foos){
                    foo->work();
                }
            }
...
        };

重新实现一个方法是没有问题的。但是当方法的数量增加时,代码变得非常湿。我的意思是,我感觉不太好复制粘贴 foreach 循环,比方说,10 个方法。

如果所有方法都具有相同的签名,您可以使用方法指针:

class Foo{
  public:
    virtual void work() = 0;
    virtual void rest() = 0;
};

class FooComposite : public Foo {
  std::vector<Foo *> foos;

  void do_all(void (Foo::*method)()) {
    for (auto foo : foos) {
      (foo->*method)();
    }
  }

  void work() override {
    do_all(&Foo::work);
  }
  void rest() override {
    do_all(&Foo::rest);
  }
};

如果您只想摆脱循环,但不介意重复方法名称,则可以将迭代(以及可能的任何错误处理)封装在 Composite 模板中,然后您可以使用 lambda 将调用转发到组合的每个元素。

template <typename ElementType>
class Composite : public ElementType {
 private:
    std::vector<ElementType*> container;

 protected:
    template < typename Fn>
    auto apply (Fn && fn) {
        for (auto& e : container) {
            fn(*e);
        }
    }
};

class Foo{
 public:
    virtual void work() = 0;
};

class FooLeaf : public Foo{
    virtual void work() override { }
};

class FooComposite : public Composite<Foo> {
    virtual void work() override {
        return apply([](Foo& f){f.work();});
    }
};

更好的是,您可以通过 Composite class 模板将添加的元素封装到复合中,这可以说是属于它的地方。 apply 的实现依赖于一些 C++14 类型推导特性,使其更易于编写和查看。