其他分享
首页 > 其他分享> > c – 父母注册孩子的方法:如何避免设计反模式?

c – 父母注册孩子的方法:如何避免设计反模式?

作者:互联网

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的子类的一些成员函数(返回void,无参数).这似乎是一个糟糕的设计:父母不应该意识到他们的孩子.但是,将功能写入每个子类会导致代码重复.我想让孩子们尽可能地瘦.

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

解决方法:

您可以使用方法指针.

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

标签:c,anti-patterns
来源: https://codeday.me/bug/20190901/1787135.html