Dug*_*las 5 c++ inheritance design-patterns stl decorator
我有一个向量和几个类(位于不同的文件中)来修改它.
我希望全局访问std::vector
,但只有在派生类中,当每个调用存储前一个结果时,最后一个对象应该返回总结果
你能解释一下如何使用Decorator模式构建高性能接口std::vector
吗?
我可能错了,可能需要其他模式.
// A.h
class A () {
public :
vector<int> set(vector<int> &vec);
//return total result
vector<int> get() {
return vector;
}
};
// B.h
class B () {
//add new elements into vector
//for example, add 2,3,4
};
// C.h
class C () {
//remove some elements from vector
//for example, remove last element
};
//...
// main.cpp
#include "A.h"
#include "B.h"
#include "C.h"
int main () {
vector<int> set;
set.push_back(1); //1
C obj(new B(new A()));
obj.set(set);
obj.get(); // stores 1,2,3 (added by classes A, B, C)
}
Run Code Online (Sandbox Code Playgroud)
所以,我不想这样做:
vector<int> set1;
set1.push_back(1);
A *A_init;
A_init->set(set1); //add 1
vector<int> set2 = A_init->get();
B *B_init;
B_init->set(set2); //add 2, stores 1,2
vector<int> set3 = B_init->get();
C *C_init;
C_init->set(set3); //add 3, stores 1,2,3
vector<int> set4 = C_init->get();
/..
Run Code Online (Sandbox Code Playgroud)
我想这样做:
vector<int> set;
set.push_back(1);
C obj(new B(new A()));
obj.set(set);
obj.get(); // stores 1,2,3
Run Code Online (Sandbox Code Playgroud)
我有一个模式装饰器的简单实现.
但这不是我需要的((
#include <iostream>
#include <memory>
class A {
public:
virtual void operation() = 0;
};
class Component : public A {
public:
virtual void operation() {
std::cout<<"World!"<<std::endl;
}
};
class B : public A {
std::unique_ptr<A> add;
public:
B(A *component): add(component) {}
virtual void operation() {
std::cout << ", ";
add->operation();
}
};
class C : public A {
std::unique_ptr<A> add;
public:
C(A *component): add(component) {}
virtual void operation() {
std::cout << "Hello";
add->operation();
}
};
int main() {
C obj(new B(new Component()));
obj.operation(); // prints "Hello, World!\n"
return 0;
}
Run Code Online (Sandbox Code Playgroud)
PS:对不太清楚解释,因为我不太懂英语
根据你的描述,装饰器不是要考虑的模式。
\n\n在我看来,您只是想设置一个变压器链来对公共向量 \xe2\x80\x93 进行操作,即一个简单的函数组合。这与装饰器的不同之处在于与核心对象的关系——您不是构建一些东西来代替向量,而是构建一些东西来对其进行操作。现在,当您使用多个变压器时,理论上您可以将第二个及以后的变压器想象为装饰器,但考虑到所涉及的对象的简单性,尝试将 GoF 装饰器实现应用于您的情况可能会有点矫枉过正。
\n\n你可以通过做这样的事情来接吻:
\n\n#include <vector>\n\nusing namespace std;\ntypedef vector<int> ivec;\n\nivec& a(ivec& v) {\n v.push_back(1);\n return v;\n}\n\nivec& b(ivec& v) {\n v.push_back(2);\n v.push_back(3);\n v.push_back(4);\n return v;\n}\n\nivec& c(ivec& v) {\n v.pop_back();\n return v;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n共有三个简单的转换函数,每个函数的编写都是为了将一个函数的输出直接输入到下一个函数的输入中。然后你可以做类似的事情:
\n\nivec& xform(ivec& v) {\n return c(b(a(v)));\n}\n\nivec v;\nxform(v);\n
Run Code Online (Sandbox Code Playgroud)\n\n如果您只想静态构建最终转换并应用它。
\n\n作为替代实现,假设您想动态构建一组变压器构建一组变压器。在这种情况下,您可以将函数推入变压器向量中并一一应用它们:
\n\n#include <vector>\nusing namespace std;\n\ntypedef ivec& (*ivec_xformer)(ivec&);\ntypedef vector<ivec_xformer> xform_vec;\nxform_vec xforms;\nxforms.add(&a);\nxforms.add(&b);\nxforms.add(&c);\n\nivec v;\nfor (xform_vec::iterator i = xforms.begin(); i != xforms.end(); ++i) {\n (*i)(v);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n顺便说一句,最后的循环可以使用boost::bind
and进一步“简化”std::for_each
顺便说一句,如果您愿意
动态变压器链与责任链有一些相似之处,除了没有让特定对象通过“处理”请求来停止链的概念,即没有真正的责任此解决方案相关的\ xe2\x80\x93 每个函数在向量上获得相同的裂纹。我建议这种模式需要一个更好的名称 \xe2\x80\x93 ,这个名称可能已经存在,因为面向对象编程中的这种函数组合并不罕见,但目前我无法理解。
\n