Reputation: 91
Need help...
I have 3 classes, Manager which holds 2 pointers. One to class A another to class B . A does not know about B and vise versa.
A does some calculations and at the end it puts 3 floats into the clipboard. Next, B pulls from clipboard the 3 floats, and does it's own calculations. This loop is managed by the Manager and repeats many times (iteration after iteration).
My problem: Now class A produces a vector of floats which class B needs. This vector can have more than 1000 values and I don't want to use the clipboard to transfer it to B as it will become time consumer, even bottleneck, since this behavior repeats step by step.
Simple solution is that B will know A (set a pointer to A). Other one is to transfer a pointer to the vector via Manager But I'm looking for something different, more object oriented that won't break the existent separation between A and B
Any ideas ?
Many thanks
David
Upvotes: 4
Views: 3957
Reputation: 76848
As has been pointed out, you can just use an std::vector<float>
as shared storage, as long as A
and B
do not run in different threads. The Manager
could manage this storage. When A
starts its work, it could request a range from that vector to store it's results. When it is done, the Manager
calls B
and hands it the range that has just been filled with values by A
. This avoids any copying.
Upvotes: 0
Reputation: 179991
The problem is solved once you realize that neither class A
nor class B
should be tyring to manage the shared data storage, as it's not exclusive to either. Hence, you are right in assuming that the Manager
should do so.
For the best performance, don't pass a pointer to the vector to A and B. Pass a raw float*
instead, as this saves a level of indirection. A compromise would be to pass a boost::array &
Upvotes: 0
Reputation: 75665
The clipboard is a crazy way to transfer data between two entities.
If B implements a generic interface such as IConsumer, the manager can pass this interface to A and A can call B's method directly with the payload:
class IConsumer {
public:
virtual void consume(const vector<float>& data) = 0;
};
class B: public IConsumer {
public:
virtual void consume(const vector<float>& data) { ... }
...
};
class A {
public:
virtual void produce(IConsumer& consumer) {
vector<float> data;
...
consumer.consume(data);
}
...
};
void Manager::tick() {
a->produce(*b);
}
Upvotes: 3
Reputation: 10988
It kind of sounds like you are writing a producer / consumer pair, who may communicate more easily over a (probably thread-safe) queue of floats.
In other words: the "queue" is like the vector you are currently using. Both A and B will have a reference to this queue. A runs calculations, and writes floats to the queue (possibly three at a time, if that's what you need). B checks the queue, or possibly is "signaled" by A that the queue is ready, and grabs the floats from the queue to process them.
For more info, google (or search Stack Overflow) for "producer consumer" and/or "queue", you'll probably find a lot of useful info.
(e.g. Multithreaded Work Queue in C++)
Upvotes: 9
Reputation: 13929
Create a vector and pass it by using "pass by reference" to A and B in your iterations.
Upvotes: 1