tags:

views:

73

answers:

2

Hi, all

Is it possible to have a vector without specializing it?

My problem is: I have an abstract class N4GestureRecognizer and a couple of subclasses of it. So in a Controller class I want to have a vector<N4GestureRecognizer> recognizers_ but since it is abstract I cannot. How can I store this recognizers in a vector or collection or list or whatever is loop-able in standard c++?

+5  A: 

Store them as pointers. Either pure pointers or some smart pointer class.

EXTRA Actually, pointers are the only way even if the class is not abstracts, but is subclassed and child classes are intended to be used in the vector. Why: std::vector allocates sizeof(T) bytes for each element, but sizeof(derivedFromT) could be bigger than sizeof(T). You will be able to push a child object into the vector, but it can cause unpredictable issues at run time.

Managing vectors of pointers is a pain, of course, but as far as I remember, boost contains some smart pointers to simplify the task.

Gobra
Thanks, very simple answer;)
nacho4d
I'm afraid it's the only way.
Gobra
And these days the standard has smart pointers: std::tr1::shared_ptr<>
FuleSnabel
The result at runtime of pushing derived classes into a vector like this is not "unpredictable". It's called slicing, and it is quite predictable (though maybe unexpected by a novice).
SoapBox
The slicing itself it predictable :) I mean that executing of the app won't be predictable.
Gobra
Let me point out: http://www.boost.org/doc/libs/1_44_0/libs/ptr_container/doc/ptr_container.html
sellibitze
+1  A: 

What you need is a std::vector< std::shared_ptr<N4GestureRecognizer> >.

If your std lib comes without std::shared_ptr (it's part of the next C++ standard, expected to be published next year), it might come with std::tr1::shared_ptr, which is the same (as a addition to the current C++ standard by the official Technical Report 1). If that also fails, there's always boost, which has boost:shared_ptr (which is the predecessor of std::tr1::shared_ptr and std::shared_ptr).

Note: Don't use naked pointers (std::vector<N4GestureRecognizer*>). There's almost no way to make this safe so that it doesn't leak.

sbi
Although if you can use boost, `ptr_vector` is often a better solution than a `std::vector` of `shared_ptr`.
Charles Bailey