Frage

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

I'd like fn to be some member function (returns void, no parameters) of child class of Base. It seems like a bad design: parents should not be aware of their childs. However, to write the functionality into every child class leads to code duplicity. I'd like to have the childs as thin as possible.

What would be the best design to achieve the desired functionality?

War es hilfreich?

Lösung

You can use method pointers.

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()

If you want better type safety, you should use dynamic_cast, but you need to add a virtual destructor so that the dynamic type inference can be made:

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

Andere Tipps

Say hello to std::function<void()>, which performs exactly the task of abstracting any function which returns void and has no parameters.

Edit: Why not simply use a virtual function? Like

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

Does limit you to only one overriding function per derived class, though.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top