3
struct Base {
  void foo(??? fn) {
    // do something with fn
  }
};

struct A : Base {
  A() : Base() { ... }
  void aa() { ... }
  void aaa() { ... }
};

struct B : Base {
  B() : Base() { ... }
  void bb() { ... }
};

int main() {
  A a, B b;
  a.foo(a.aa); // foo works with aa()
  a.foo(a.aaa); // foo works with aaa()
  b.foo(b.bb); // foo works with bb()
  return 0;
}

我想fn成为Base. 这似乎是一个糟糕的设计:父母不应该意识到他们的孩子。但是,将功能写入每个子类会导致代码重复。我想让孩子尽可能瘦。

实现所需功能的最佳设计是什么?

4

2 回答 2

3

Say hello to std::function<void()>,它完全执行抽象任何返回 void 且没有参数的函数的任务。

编辑:为什么不简单地使用虚函数?像

struct Base {
private:
  virtual void fn() = 0;
public:
  void foo() {
    // do something with fn
  }
};

struct A : Base {
  A() : Base() { ... }
  void fn() { ... }
};

struct B : Base {
  B() : Base() { ... }
  void fn() { ... }
};

int main() {
  A a, B b;
  a.foo(); // foo works with aaa()
  b.foo(); // foo works with bb()
  return 0;
}

但是,确实将您限制为每个派生类只有一个覆盖函数。

于 2012-07-21T00:47:56.117 回答
2

您可以使用方法指针。

struct Base {
  template <typename D>
  void foo(void(D::*fn)()) {
    D *d = static_cast<D *>(this);
    (d->*(fn))();
  }
};

  A a; B b;
  a.foo(&A::aa); // foo works with aa()
  a.foo(&A::aaa); // foo works with aaa()
  b.foo(&B::bb); // foo works with bb()

如果你想要更好的类型安全,你应该使用dynamic_cast,但你需要添加一个虚拟析构函数,以便可以进行动态类型推断:

struct Base {
  virtual ~Base() {}
  template <typename D>
  void foo(void(D::*fn)()) {
    D *d = dynamic_cast<D *>(this);
    if (d == 0) throw 0;
    (d->*(fn))();
  }
};

  b.foo(&B::bb); // ok
  b.foo(&A::aa); // exception thrown
于 2012-07-21T00:55:02.500 回答