我有一个 vector 和几个类(位于不同的文件中)来修改它。
我希望全局访问std::vector
,但只能在派生类中访问
当每个调用存储前一个结果时,最后一个对象应该返回总结果
您能解释一下如何使用带有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)
}
所以,我不想这样做:
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();
/..
我想这样做:
vector<int> set;
set.push_back(1);
C obj(new B(new A()));
obj.set(set);
obj.get(); // stores 1,2,3
我对模式装饰器进行了简单的修复 但这并不是我所需要的((
#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;
}
PS: 很抱歉没有那么清楚的解释,因为我不太懂英语
答案 0 :(得分:4)
根据您的描述,装饰器不是要看的模式。
听起来我只是想设置一个变换器链来操作一个共同的向量 - 即一个简单的功能组合。这与装饰器的区别在于与核心对象的关系 - 你没有为站在中构建一些向量,你正在为构建一些东西在上运作。现在,当您使用多个变换器时,理论上可以将第二个和后来的变换器想象为第一个变换器 decorators ,但考虑到所涉及对象的简单性,尝试将GoF装饰器实现应用于您的情况可能是会有点矫枉过正。
你可以通过这样的方式来结婚:
#include <vector>
using namespace std;
typedef vector<int> ivec;
ivec& a(ivec& v) {
v.push_back(1);
return v;
}
ivec& b(ivec& v) {
v.push_back(2);
v.push_back(3);
v.push_back(4);
return v;
}
ivec& c(ivec& v) {
v.pop_back();
return v;
}
有三个简单的变换函数,每个函数都写入,以便一个输出可以直接输入到下一个输入。然后你可以做类似的事情:
ivec& xform(ivec& v) {
return c(b(a(v)));
}
ivec v;
xform(v);
如果您想静态地构建最终转换并应用它。
作为替代实现,假设您想构建一组动态动态的变换器。在这种情况下,您可以将函数推送到变换器的向量中并逐个应用它们:
#include <vector>
using namespace std;
typedef ivec& (*ivec_xformer)(ivec&);
typedef vector<ivec_xformer> xform_vec;
xform_vec xforms;
xforms.add(&a);
xforms.add(&b);
xforms.add(&c);
ivec v;
for (xform_vec::iterator i = xforms.begin(); i != xforms.end(); ++i) {
(*i)(v);
}
如果您愿意,可以使用boost::bind
和std::for_each
进一步“简化”此循环(btw)。
变形金刚的动态链与责任链有一些相似之处,除了没有特定对象的概念通过“处理”请求来阻止链,即没有真正的责任与此解决方案相关联 - 每个函数在向量处获得相同的破解。我建议这个模式需要一个更好的名字 - 一个可能已经存在,因为OO编程中的这种功能组合并不罕见,但目前我没有。
答案 1 :(得分:3)
这就是:
#include <vector>
#include <cstdio>
/* A class that operates on an std::vector. */
class Vector
{
public:
virtual std::vector<int> & getVector() = 0;
virtual void operation() = 0;
virtual ~Vector() {}
};
/* Basic implementation of Vector. */
class BasicVector : public Vector {
public:
BasicVector(std::vector<int> & refVector) : intVector(refVector) {}
void operation() {
intVector.push_back(2);
}
std::vector<int> & getVector() {
return intVector;
}
private:
std::vector<int> & intVector;
};
/* First decorator. */
class VectorDecorator1 : public Vector
{
public:
VectorDecorator1(Vector & refVec) : intVec(refVec) {}
std::vector<int> & getVector() {
return intVec.getVector();
}
void operation() {
intVec.operation();
intVec.getVector().push_back(3);
}
private:
Vector & intVec;
};
/* Second decorator. Others can be easily added in the future. */
class VectorDecorator2 : public Vector
{
public:
VectorDecorator2(Vector & refVec) : intVec(refVec) {}
std::vector<int> & getVector() {
return intVec.getVector();
}
void operation() {
intVec.operation();
intVec.getVector().push_back(4);
}
private:
Vector & intVec;
};
int main(int argc, char *argv[])
{
std::vector<int> my_vector;
my_vector.push_back(1);
BasicVector basic_vector(my_vector);
VectorDecorator1 vd1(basic_vector);
VectorDecorator2 vd2(vd1);
vd2.operation();
for(unsigned i = 0; i < my_vector.size(); i++) {
printf("%d\n", my_vector[i]);
}
return 0;
}
注意:如果您愿意,可以轻松更改BasicVector以使其在自己的std :: vector(而不是引用)上运行。