到目前为止,在两个特定的存储库之间,我使用了接口类(具有继承性),而最近我已使用std :: function()和std :: bind()将其替换为回调函数。
使用类似界面的旧方法,我最终得到了这样的结果:
//a.hpp
#include "b.hpp"
class A{
public:
A(InterfaceB* pb) : m_pb(pb) {};
void bar(){m_pb->foo();};
private:
InterfaceB* m_pb;
};
-
//b.hpp
#include <iostream>
class InterfaceB{
public:
virtual void foo() = 0;
};
class B : public InterfaceB {
public:
void foo(){ std::cout << "hi"<< std::endl; };
};
-
//main.cpp
#include "a.hpp"
#include <memory>
int main(){
InterfaceB* pb = new B;
A a(pb);
a.bar();
delete pb;
}
-
在UML中,我会像这样绘制上面的小例子:
为了减少存储库(这里是A和B类)之间的依赖性,我删除了接口并改用了函数包装器。
//a_callback.hpp
#include <functional>
class A{
public:
void setBcallback(std::function<void(void)> callback){m_callback = callback;};
void bar(){m_callback();};
private:
std::function<void(void)> m_callback;
}
-
//b_callback.hpp
#include <iostream>
class B {
public:
void foo(){ std::cout << "hi"<< std::endl; };
}
-
//main.cpp
#include "a_callback.hpp"
#include <functional>
int main(){
A a;
B b;
a.setBcallback(std::bind(&B::foo, &b));
a.bar();
}
-
这对我来说是个棘手的问题,我对Google的运气不满意。 C ++的std :: bind()/ std :: function()和UML的<< bind >>相互转换。所以我的问题是,如何在类图上显示函数包装的使用? 根据我的发现,我可能会这样做:
但是它只是感觉松散和不足。任何帮助将不胜感激!
该问题先前已被标记为重复项:How to represent Callback in UML Class Diagram。 但是我的问题是C ++特有的,并且说“原始”被标记为Java,不幸的是我没有得到任何帮助。我的问题不是我认为可以解释的“如何在UML中显示回调”,而是更多的“如何在UML中显示std :: bind()”,我认为这比较棘手。这里有两件事,一是使用bind()设置函数包装器,第二是通过包装器进行调用。我只是看不到上面的那个线程如何解决这个特定的问题。谢谢!
答案 0 :(得分:1)
<<bind>>
依赖项涉及UML template绑定:
TemplateBinding是TemplateableElement和 指定实际替换的模板 ParameterableElements的正式TemplateParameters 模板。
template binding是一个特殊的实现依赖项,它表明类是模板的特化,并放置了模板替换。
一个典型的例子是:
using void_function = std::function<void(void)> ;
在C ++中,std::bind()
动态地将参数绑定到可调用对象。 这是完全不同的语义。
如果要在UML中显示此内容,它不会那么有用。您可以:
显示绑定返回的匿名类型是可调用的模板实例化,带有一个用B代替的自变量(非常类似于上面的图)。
如果有用,请表明此匿名类依赖于B。
如果有用,请显示从A到此匿名类的可选关系(0..1),要理解的是,其他匿名类也可能具有替代关系(如果要说明,可以使用OCL约束并在图表上明确指出它们是互斥的)。
不幸的是,无论您画什么,它都不会像您的C ++设计那样通用和强大,并且对理解也无济于事。
UML图的目标不是图形化编程,而是对内部结构的洞察力。因此,我强烈建议您保持简单:
唯一真实的关系是A与回调的抽象可调用类之间。这必须在图表上进行。
您还可以显示此抽象回调可以依赖于图中的其他相关类。对这些依赖关系的注释可以用简单的词来解释这些依赖关系表达了对成员函数的绑定。