CLOS有一个很好的概念:前、后和:外周方法。
在主方法之前调用
方法围绕:before+primary+:after序列调用。
“前”、“后”和“:循环”方法是链式的,而不是重写的。假设父类和子类都定义了foo方法和: parent方法。子方法的foo方法重写父方法的foo方法,但在调用该重写方法之前,子方法和父方法都会被调用。
Python装饰器提供了类似于CLOS :的东西。在C++中没有这样的东西。它必须手工轧制:
class Child : public Parent {
virtual void do_something (Elided arguments) {
do_some_preliminary_stuff();
Parent::do_something (arguments);
do_some_followup_stuff();
}
};缺点:
对于某些人来说,这是一种反模式。paradigm.
do_something而需要调用外祖父母,则需要类的扩展程序遵循相同的。当我使用口味(CLOS的前身)时,我发现这些概念非常方便。我已经在几个地方使用了上面的解决方法,也有一些人将其作为反模式提出了挑战。(其他人在其他地方也模仿过,因此这种嘲讽并不是普遍的。)
问题是:这在C++中被认为是一种反模式吗?还有更好的解决办法吗?
发布于 2011-07-08 09:53:29
这是我能做的,但还是有点丑。
基本上,我把实际的工作放在一个单独的钩子中,这样在处理方法中就没有调用前/后挂钩了。在继承链中,您可以完全控制是否要添加预/后挂钩和钩子调用的顺序(在子挂钩之前或之后调用父钩子)。
#include <iostream>
#define C(s) std::cout << s << std::endl;
class Parent {
public:
virtual void do_something(int arg) {
do_some_pre_hook();
do_some_hook(arg);
do_some_post_hook();
}
virtual void do_some_pre_hook() {
C("parent pre_hook");
}
virtual void do_some_post_hook() {
C("parent post_hook");
}
virtual void do_some_hook(int arg) {
//this is where you actually do the work
}
};
class Child : public Parent {
public:
typedef Parent super;
virtual void do_some_pre_hook() {
super::do_some_pre_hook();
C("Child pre_hook");
}
virtual void do_some_post_hook() {
super::do_some_post_hook();
C("Child post_hook");
}
};
class GrandChild : public Child {
public:
typedef Child super;
virtual void do_some_pre_hook() {
super::do_some_pre_hook();
C("GrandChild pre_hook");
}
virtual void do_some_post_hook() {
super::do_some_post_hook();
C("GrandChild post_hook");
}
virtual void do_some_hook(int arg) {
//this is where you actually do the work
C("GrandChild hook");
}
};
int main() {
GrandChild gc;
gc.do_something(12);
}注意事项:理想情况下,您可以使用AOP c++编译器或编译器扩展来执行这样的任务,但上次我尝试时它并不是很稳定……
发布于 2011-07-08 10:15:08
使用(std/boost)::shared_ptr,您可以很好地了解这方面的基础知识。有关详细信息,请参阅此处:http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/sp_techniques.html#wrapper
要获得您提到的继承行为,只需要前缀/后缀函数调用父类中的前缀/后缀函数。
发布于 2011-07-08 09:39:05
我并不认为这与其他语言相同或类似,但我认为非虚拟界面()成语适用于您的问题:
class parent {
public:
void foo()
{
before_foo();
do_foo();
after_foo();
}
protected:
// you can make those pure virtual with an implentation, too
virtual void before_foo() { ... }
virtual void do_foo() { ... }
virtual void after_foo() { ... }
};
class child: public parent {
protected: // or private
void before_foo() { ... }
void do_foo() { ... }
// must provide a dummy after_foo that delegates to parent::after_foo
// if it is pure virtual in the parent class
};在调用p.foo()时,总是调用最派生的before_foo、after_foo和do_foo。
https://stackoverflow.com/questions/6622290
复制相似问题