gpt4 book ai didi

C++ 装饰器模式

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:21:36 24 4
gpt4 key购买 nike

我有一个 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;
}

附言:抱歉解释的不是很清楚,因为我不太懂英语

最佳答案

根据您的描述,Decorator 不是要查看的模式。

在我看来,您只是想设置一个转换器链来对一个公共(public) vector 进行操作——即一个简单的功能组合。这在与核心对象的关系方面不同于 Decorator - 你不是在构建一些东西来代替 vector ,而是在构建一些东西来对其进行操作。现在当你使用多个转换器时,理论上你可以将第二个和后面的转换器想象成第一个的装饰器,但考虑到所涉及对象的简单性,尝试将 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);

如果您只想静态构建最终转换并应用它。

作为替代实现,假设您想要动态构建一组转换器。在这种情况下,您可以将函数推送到转换器 vector 中并一个一个地应用它们:

#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::bindstd::for_each 进一步“简化”这个循环。

转换器的动态链与责任链有些相似,除了没有让特定对象通过“处理”请求来停止链的概念,即没有真正的责任 与此解决方案相关联——每个函数在 vector 上得到平等的破解。我建议这种模式需要一个更好的名称——一个可能已经存在的名称,因为这种函数组合在 OO 编程中并不少见,但目前我还没有想到。

关于C++ 装饰器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8764247/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com