I've a vector and several classes (located in separate files) to modify the one.
I want to have global access to the std::vector
, but only within the derived classes
when each call stores the result of previous and the last object should return the total result
Could you explain how to build a high-performance interface using Decorator pattern with std::vector
?
I may be wrong, and may need other pattern.
// 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)
}
So, I don't want to do like this:
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();
/..
And I want to do like this:
vector<int> set;
set.push_back(1);
C obj(new B(new A()));
obj.set(set);
obj.get(); // stores 1,2,3
I've a simple impementation of a pattern Decorator.
But it is not quite what I need ((
#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: Sorry for not so clear explanation, because I don't know English so well
Decorator in C++ Decorator is a structural pattern that allows adding new behaviors to objects dynamically by placing them inside special wrapper objects, called decorators. Using decorators you can wrap objects countless number of times since both target objects and decorators follow the same interface.
In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other objects from the same class.
Yes, there are. Lazy initialization, singleton, object pool, object state etc.
Functions, data, and objects in C and C++ programs are represented internally by their decorated names. A decorated name is an encoded string created by the compiler during compilation of an object, data, or function definition.
From what you've described, Decorator is not the pattern to be looking at.
It sounds to me like you simply want to set up a chain of transformers to operate upon a common vector – i.e. a simple functional composition. This differs from Decorator in terms of the relationship to the object at the core - you are not building something to stand in for a vector, you are building something to operate upon it. Now when you take multiple transformers, you could theoretically imagine the second and later transformers as decorators of the first, but given the simplicity of the objects involved, trying to apply the GoF decorator implementation to your situation is probably going to be overkill.
You can KISS by doing something like this:
#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;
}
There are three simple transformation functions, each written so that the output of one can be fed right into the input of the next. Then you can do something like:
ivec& xform(ivec& v) {
return c(b(a(v)));
}
ivec v;
xform(v);
if you want to just build up your final transform statically and apply it.
As an alternate implementation, let's say you wanted to build up a set of transformers dynamically. In that case, you can push the functions into a vector of transformers and apply them one by one:
#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);
}
This loop at the end, btw, can be further "simplified" with boost::bind
and std::for_each
if you're so inclined.
The dynamic chain of transformers bears some resemblance to a Chain of Responsibility, except that there's no concept of having a particular object stop the chain by "handling" the request, i.e. there's no real responsibility associated with this solution – each function gets an equal crack at the vector. I'd suggest this pattern needs a better name – one probably already exists out there, as this kind of functional composition in OO programming is not uncommon, but it eludes me at the moment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With