I have a class that's inhenerently non-copyable (a thread, so there's no copy semantics that make sense), and I want to have a largeish 'array' of these, identically constructed with a non-default constructor. Note that the array is fixed size.
I can only use the default constructor with C++ arrays, unless I initialise each one independently.
Thread myArray[128]; // uses default constructor - wrong
I can list the object constructors and parameters explicitly, but that's verbose and ugly
Thread myArray[128] = { Thread(params,...), Thread(params,...), ... x 128 ; // ugly
It seems I can't use stl vectors because the object is non-copyable - event though the vector never changes size. I guess the constructor actually does copying!
std::vector<Thread> myVector(128, Thread(params,...));// won't compile
The way I've though of doing this is with an开发者_运维知识库 array of smart pointers and an initialization loop, but maybe I'm missing something:
Is there any other way - maybe with boost containers, or a different container type?
This may seem like totally crazy (and it probably is), but...
struct ThreadInitValues{
// your actual params
int i;
float f;
};
struct Thread{
Thread(int i = _init.i, float f = _init.f)
: _i(i)
, _f(f)
{}
static ThreadInitValues _init;
private:
// uncopyable
Thread(Thread const&);
Thread& operator=(Thread const& other);
// your actual member
int _i;
float _f;
};
ThreadInitValues Thread::_init;
int main(){
Thread::_init.i = 5;
Thread::_init.f = 3.14f;
Thread arr[128];
}
Maybe this works out for you. :) Of course, you now need to watch out if the array is initialized in multithreaded code itself...
A vector of smart pointers, with each instance dynamically
allocated, is definitely the simplest way. Otherwise (and I'd
only do this if absolutely necessary), you can more or less
emulate what std::vector
does internally. Something along the
lines of:
union
{
double just_to_ensure_alignment;
unsigned char data[ sizeof(Thread) * elementCount ];
} array;
// construct...
for ( int i = 0; i != elementCount; ++ i )
new (data + i * sizeof(Thread)) Thread(params,...);
// access...
Thread& getAt( int i )
{
return reinterpret_cast<Thread*>( data + i * sizeof(Thread) );
}
(I'd actually wrap this in a class, if only to be able to use
operator[]
instead of getAt
.)
For new compilers supporting r-value references, being copyable is not necessary for vector elements AFAIK. To use it without copying 128 push_back's should be used (creating new object each time), because creting several objects from a single one is a copying :).
If this way is not available, try boost::ptr_vector or std::vector of boost::shared_ptr.
I am not that much big programmer. But did you try this
std::vector<YourObject *> temp_Vec;
for(int i=0;i<128;++i)
temp_Vec.push_back(new YourObject(arguments));
精彩评论