Array<Value> question

I have a set of sliders (24), that each should refer to a Value. The Value objects are declared and updated from midi in another class.

This may be a silly newbie question, but can I make an Array to hold all the Value objects?


Thankyou for your patience!


The answer is yes - it should be fine.  But it's actually a very important question.  Different arrays have different types of behaviour, and Value has a slightly odd behaviour when you copy it as well (it forgets about any listeners). 

The array behaviour comes from how it deals with expansion once you've filled up the space it had allocated.  Array and std::vector (the standard C++ alternative) both hold the memory in one continuous block.  If you add more objects than they have space reserved for they grab a new bigger contiguous block and move everything across.  

  • juce::Array<> calls memcpy and just copies the data from one location to another. That's fine, except if your object has a pointer back to itself (or otherwise depends on being in a fixed location in memory).  So it's okay for most objects but won't work with, say, a std::function<> object.  Array<std::function<>> breaks, at least on the C++ library I'm using. 
  • std::vector<> is slightly better behaved with most objects.  It uses the move or copy constructors when it needs to expand.  However, because Value doesn't copy the listeners when its copy constructor is called it doesn't work well with a Value object. 

The really safe alternative for complicated objects, or anywhere you need polymorphic pointers, is a juce::OwnedArray*. But vector and array will often be faster, which may be important in some circumstances.  And they are a bit easier to use as you don't need to bother allocating everything separately with new

So it's not a silly question at all.  There's probably much more to it, but these are the issues I've come across..

*Jules - or an array/or vector of ScopedPointers? is there any difference?


Thankyou for your answer!


So if I use juce::Array, "ensureStorageAllocated" should make shure no copying is done and the Values don't forget the listeners?




Array won't anyway.  It's std::vector that's the problem with Value listeners.