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