装饰器模式:如何从核心类中调用(回调)装饰器包装器的一些成员
Decorator pattern: how can I call(back) some members of decorator wrappers from the core class
我正在按照下面的示例实现一个装饰器模式:
- 类
I
:是接口类,与核心类和装饰器基类共同使用。 -
A
类:为核心类 - 类
D
:为装饰基类 - 类
X
,Y
,Z
:继承装饰器基类,动态扩展核心类的功能
类A
(A::endTraining()
)中有一个方法,它在计时器变量(也存在于类A
中)的末尾触发。这个方法需要调用X
、Y
和Z
类中的某个成员。
这可能吗?这是好的练习吗?如何?
XYZ::endTraining
的指针在A
类中是否是正确的方法?(只显示相关位)
typedef void (D::*pCallback_fn)(void);
class I
{
public:
virtual void endTraining() = 0;
virtual void regTrainingCallbacks(pCallback_fn ptrFn) = 0;
};
class A: public I {
public:
void endTraining() {
//do stuff
//then do stuff in D (and its derivatives)
// by iterating through fnList
}
void regTrainingCallbacks(pCallback_fn ptrFn)
{
fnList.push_back( ptrFn );
}
private:
std::list<pCallback_fn> fnList;
};
class D: public I {
public:
D(I *inner) {
m_wrappee = inner;
}
void regTrainingCallbacks(pCallback_fn ptrFn)
{
m_wrappee->regTrainingCallbacks(ptrFn);
}
private:
I *m_wrappee;
};
class X /*,Y,Z*/ : public D {
public:
X(I *core): D(core)
{
D::regTrainingCallbacks( this->*endTraining() ); //
}
private:
void endTraining(){
//do stuff when called by A::endTraining() through D
}
};
可以做什么来代替?
解决原始设计中的一个错误,其中'trainer'(注册培训回调的实体)本身必须是回调(是否有任何理由通知器-前类A
-必须是回调本身?)
我更改了类名,以表明它们的职责。
MainTrainingProcess
替换了原来的class A
(其实例将被D
-es包装)和D
本身。
class EndTrainingListener
{
public:
virtual ~EndTrainingListener() { }
virtual void endTraining()=0;
};
class ITrainingProcess
{
public:
virtual ~ITrainingProcess() { }
virtual void regTrainingCallbacks(EndTrainingListener* callback) = 0;
};
class MainTrainingProcess : public ITrainingProcess {
public:
virtual ~MainTrainingProcess() {
// destroy other resources used during training
}
virtual void regTrainingCallbacks(EndTrainingListener* callback) {
this->listeners.push_back(callback);
}
void train() {
// do training stuff
// ...
// do my specific actions at the end of training
// ...
// finish by notifying all listeners
this->atEndTraining();
}
protected:
void atEndTraining() {
for(auto l : this->listeners) {
l->endTraining();
}
}
std::list<EndTrainingListener*> listeners;
};
class X /*Y, Z*/ : public EndTrainingListener {
public:
virtual ~X();
virtual void endTraining() {
// do specific stuff
}
};
相关文章:
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- std::包含 std::函数回调的多个包装器的向量不起作用
- 模板回调的包装器?
- CPP成员对C回调包装器的反馈
- 用C++lambda包装C回调,可以使用模板多态性
- C++ RapidJSON 解析包装在回调函数中的 JSON 对象
- 在类中包装freeglut回调的最优雅方法
- 如何将包装的C++对象传递给 Javascript 回调
- 使用 C++11 接口包装 C 回调的最佳方法是什么?
- 装饰器模式:如何从核心类中调用(回调)装饰器包装器的一些成员
- 用于包装类方法的回调函数和static_cast