Storing objects in vector - c++

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++?

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.

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.

Related

Storing dynamically created objects

Lets say I have a class Obj, and instances of them are created at run time, can I store them without new like this?
Obj my_obj;
std::vector<Obj> my_vec;
my_vec.push_back(my_obj);
Or do I have to use new?
std::vector<Obj*> my_vec;
my_vec.push_back(new Obj);
And what if I have pointers inside of my class Obj? Also, what if use the second option, do I have to clean up everything?
The question is related to heap allocated objects vs. stack objects.
There are already a few good resources on that in Stackoverflow:
Stack Memory vs Heap Memory
Stack vs Heap C++
C++ stack vs heap allocation
Why should I use a pointer rather than the object itself?
(you may want to look at all the above, each has its own angle).
But, your question is specifically about a container holding objects or pointers to objects. For this there are a few other resources:
Should I store entire objects, or pointers to objects in containers?
Is it better to save object pointer in STL container rather than object itself?
Let me summarize shortly:
Usually working with values and not pointers should be your preferred option. They are much easier to maintain and less bug-prone. Before C++11 performance considerations could be a reason for considering working with container of pointers, but since move semantics came in C++11, if you design your code properly, working with containers of values should not be costly.
Another reason for working with pointers might be polymorphism. You want your container to hold and manage different types which share the same base class. Though it seems that a container of pointers should be the solution in such a case, which is used in many examples for polymorphism in C++, this still should not be your preferred choice. The first alternative for raw pointers should be holding unique_ptr which is a smart pointer type introduced in the C++ standard library in C++11.
The other option is to model the data that you want to manage withing a class that would hide and manage your polymorphism without exposing it to the container or to the user. Let's take an example: suppose you want to manage a container of Command objects, where Command is a base class for many different actual commands. Instead of having a container of Command* or unique_ptr<Command>, rename Command to be CommandBase, then hold (wrap, hide) unique_ptr<CommandBase> inside class Command and hold in your container objects of type Command.
Another alternative would be to avoid inheritance altogether. So for different callables (our Command example) you can just use std::function.
You can also use std::variant to manage the different types (e.g. using Shape = std::variant<Circle, Triangle>;).
Hiding the fact that you are using polymorphism, or avoiding polymorphism altogether, can become quite useful in your API, with the benefits of being able to preserve proper value semantics.
More on value semantics and its benefits can be found in CppCon 2022 talk by Klaus Iglberger: Back to Basics: Cpp Value Semantics and in C++Now 2022 talk by Dave Abrahams: A Future of Value Semantics and Generic Programming, Part 1 and Part 2. The original talk on the subject, by Sean Parent: Value Semantics and Concepts-based Polymorphism, from C++Now 2012.
You can also read about value semantics in the following links:
C++ classes as value types a Microsoft blog post
Reference and Value Semantics in ISO-CPP FAQ
Value Semantics and Polymorphism a blog post by Dean Berris

Which is the right container to manage small objects which map to some other small objects?

I have a set of small objects. Each of these objects points to other objects. These pointers might be realized as actual pointers or as index into an array of the objects or something else. It might be an array of such pointers whose length might change. There might be pointers to objects of the same type and to other types, but this is known at compile time.
So, for example: I have a class Person. This person has two pointers to its parent Persons. There's another class Place. Each Person has a list of pointers to all Places he/she has visited.
In contrast to an actual family tree, I might want to change the tree from time to time by deleting/inserting some Persons.
Is there a container in the C++ Standard Library (C++ 11) for that purpose or should I better look for a dedicated memory management class?
I will have to pass the data to a C interface why I would prefer a storage method which is based on an accessible (read only) linear array.
Sounds like a great time to quote Stepanov:
Use vectors whenever you can. If you cannot use vectors, redesign your solution so that you can use vectors.
The "accessible linear array" part points to vector<Person> - none of the other containers have that feature - and the rest of your use-case doesn't suggest any specific kind storage or access. Part of it sounds like it might be cleaner if you could do vector<shared_ptr<Person>> but that would break your C interface requirement. So vector<Person> is probably your answer.
Questions:
"There might be pointers to objects of the same type and to other types, but this is known at compile time."
"These pointers might be realized as actual pointers or as index into an array of the objects or something else."
In contrast to an actual family tree, I might want to change the tree from time to time by deleting/inserting some Persons.
"Is there a container in the C++ Standard Library (C++ 11) for that purpose or should I better look for a dedicated memory management class?"
"I will have to pass the data to a C interface why I would prefer a storage method which is based on an accessible (read only) linear array."
Answers:
This could become difficult if you want to use pointers to multiple types of objects in a single container. But you could make either a raw array or a std::vector work.
If you're just using indices that would greatly simplify your "pointers to multiple types" problem. Again either a raw array or a std::vector work.
Dynamically changing raw array sizes gets sketchy fast, I'd say this is a point for std::vector.
Depending upon the time that you are willing to put in, managing your memory is a tremendous endeavor, I'd stick with a raw array or std::vector until they pried my cold dead fingers loose.
If you have C++11 using std::vector::data can make a std::vector just as usable as a raw array here, if not this would be simpler to implement as a raw array.
std::vector has numerous benefits to you as the programmer. Not the least of which is automatic memory management. So I'd lean toward std::vector where it is an option.
I prefer to use vector rather than other (list, etc) . as Bjarne said "If you know int and vector, so you know C++".
Here is the link at Youtube, as Bjarne said about vector:
Bjarne Stroustrup: Why you should avoid Linked Lists

c++ vector construct with given memory

I'd like to use a std::vector to control a given piece of memory. First of all I'm pretty sure this isn't good practice, but curiosity has the better of me and I'd like to know how to do this anyway.
The problem I have is a method like this:
vector<float> getRow(unsigned long rowIndex)
{
float* row = _m->getRow(rowIndex); // row is now a piece of memory (of a known size) that I control
vector<float> returnValue(row, row+_m->cols()); // construct a new vec from this data
delete [] row; // delete the original memory
return returnValue; // return the new vector
}
_m is a DLL interface class which returns an array of float which is the callers responsibility to delete. So I'd like to wrap this in a vector and return that to the user.... but this implementation allocates new memory for the vector, copies it, and then deletes the returned memory, then returns the vector.
What I'd like to do is to straight up tell the new vector that it has full control over this block of memory so when it gets deleted that memory gets cleaned up.
UPDATE: The original motivation for this (memory returned from a DLL) has been fairly firmly squashed by a number of responders :) However, I'd love to know the answer to the question anyway... Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?
The obvious answer is to use a custom allocator, however you might find that is really quite a heavyweight solution for what you need. If you want to do it, the simplest way is to take the allocator defined (as the default scond template argument to vector<>) by the implementation, copy that and make it work as required.
Another solution might be to define a template specialisation of vector, define as much of the interface as you actually need and implement the memory customisation.
Finally, how about defining your own container with a conforming STL interface, defining random access iterators etc. This might be quite easy given that underlying array will map nicely to vector<>, and pointers into it will map to iterators.
Comment on UPDATE: "Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?"
Surely the simple answer here is "No". Provided you want the result to be a vector<>, then it has to support growing as required, such as through the reserve() method, and that will not be possible for a given fixed allocation. So the real question is really: what exactly do you want to achieve? Something that can be used like vector<>, or something that really does have to in some sense be a vector, and if so, what is that sense?
Vector's default allocator doesn't provide this type of access to its internals. You could do it with your own allocator (vector's second template parameter), but that would change the type of the vector.
It would be much easier if you could write directly into the vector:
vector<float> getRow(unsigned long rowIndex) {
vector<float> row (_m->cols());
_m->getRow(rowIndex, &row[0]); // writes _m->cols() values into &row[0]
return row;
}
Note that &row[0] is a float* and it is guaranteed for vector to store items contiguously.
The most important thing to know here is that different DLL/Modules have different Heaps. This means that any memory that is allocated from a DLL needs to be deleted from that DLL (it's not just a matter of compiler version or delete vs delete[] or whatever). DO NOT PASS MEMORY MANAGEMENT RESPONSIBILITY ACROSS A DLL BOUNDARY. This includes creating a std::vector in a dll and returning it. But it also includes passing a std::vector to the DLL to be filled by the DLL; such an operation is unsafe since you don't know for sure that the std::vector will not try a resize of some kind while it is being filled with values.
There are two options:
Define your own allocator for the std::vector class that uses an allocation function that is guaranteed to reside in the DLL/Module from which the vector was created. This can easily be done with dynamic binding (that is, make the allocator class call some virtual function). Since dynamic binding will look-up in the vtable for the function call, it is guaranteed that it will fall in the code from the DLL/Module that originally created it.
Don't pass the vector object to or from the DLL. You can use, for example, a function getRowBegin() and getRowEnd() that return iterators (i.e. pointers) in the row array (if it is contiguous), and let the user std::copy that into its own, local std::vector object. You could also do it the other way around, pass the iterators begin() and end() to a function like fillRowInto(begin, end).
This problem is very real, although many people neglect it without knowing. Don't underestimate it. I have personally suffered silent bugs related to this issue and it wasn't pretty! It took me months to resolve it.
I have checked in the source code, and boost::shared_ptr and boost::shared_array use dynamic binding (first option above) to deal with this.. however, they are not guaranteed to be binary compatible. Still, this could be a slightly better option (usually binary compatibility is a much lesser problem than memory management across modules).
Your best bet is probably a std::vector<shared_ptr<MatrixCelType>>.
Lots more details in this thread.
If you're trying to change where/how the vector allocates/reallocates/deallocates memory, the allocator template parameter of the vector class is what you're looking for.
If you're simply trying to avoid the overhead of construction, copy construction, assignment, and destruction, then allow the user to instantiate the vector, then pass it to your function by reference. The user is then responsible for construction and destruction.
It sounds like what you're looking for is a form of smart pointer. One that deletes what it points to when it's destroyed. Look into the Boost libraries or roll your own in that case.
The Boost.SmartPtr library contains a whole lot of interesting classes, some of which are dedicated to handle arrays.
For example, behold scoped_array:
int main(int argc, char* argv[])
{
boost::scoped_array<float> array(_m->getRow(atoi(argv[1])));
return 0;
}
The issue, of course, is that scoped_array cannot be copied, so if you really want a std::vector<float>, #Fred Nurk's is probably the best you can get.
In the ideal case you'd want the equivalent to unique_ptr but in array form, however I don't think it's part of the standard.

How should smart pointers get down casted?

Do smart pointers handle down casting, and if not what is a safe way of working around this limitation?
An example of what I'm trying to do is having two STL vectors (for example) containing smart pointers. The first contains smart pointers to a base class while the second contains smart pointers to a derived class. The smart pointers are referenced counted, e.g. similar behaviour to Boost's shared_ptrs, but hand-rolled. I've included some sample code that I whipped up to provide an example:
vector<CBaseSmartPtr> vecBase;
vector<CDerivedSmartPtr> vecDer;
...
CBaseSmartPtr first = vecBase.front();
vecDer.push_back(CDerivedSmartPtr(dynamic_cast<CDerived*>(first.get()));
This seems not safe to me, as I think I'm ending up with two smart pointers managing the same object. At some point down the track this is probably going to result in one of them freeing the object while the other still holds references to it.
What I'd hope for but don't think will work is a straight down-cast while keeping the same object, e.g.
dynamic_cast<CDerivedSmartPtr>(first)
Should I be looking to change the second container to also use CBaseSmartPtr and downcast on usage only? Are there other solutions?
Smart pointers can handle downcasting, but it's not automatic. And getting const-correctness in can be a bit complex (I've used our smart pointer implementation in interview questions, there's some template trickery involved). But many users of smart pointers never instantiate their smart pointers with const-qualified types anyway.
The first thing you need to get correct is the counter. Since you may need to share a counter between smart_ptr<Base> and smart_ptr<Derived>, the counter type should not depend on the type argument. In general, this is not a big deal anyway. A counter is merely a size_t, probably wrapped in a class. (Note: there are alternative smart pointer designs, but the question strongly suggests a counter is used)
A cast towards base should be fairly trivial. Hence, your smart_ptr should have a constructor taking a smart_ptr. In this ctor, add a line static_cast<T*>((U*)0);. This doesn't generate code, but prevents instantiation when T is not a base of U (modulo const qualifications).
The other way around should be an explicit cast. You can't programatically enumerate all bases of T, so smart_ptr<T> cannot derive from smart_ptr<Base1_of_T>, smart_ptr<Base2_of_T>, ... Hence, a dynamic_cast<smart_ptr<T> > won't work. You can provide your own smart_dynamic_cast<SPT>(smart_ptr<U> const& pU). This is best implemented as a function returing an SPT. In this function, you can simply do a return SPT(dynamic_cast<SPT::value_type*>(&*pU)).
The property you want is covariance in the pointed-to type. That is, if D isa B, then you want smartptr<D> isa smartptr<B>. I don't think this is elegantly supported at all in C++, but as always, there are template/overload hacks available.
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/pointer_cast.html gives a dynamic cast that works on regular and boost::smart_ptr. You should learn from the implementation if you don't want to just use Boost's.
Follow the thread here in one of the boost mailing lists. It shows how one can implement smart-pointer downcasting in case of boost::shared_ptr. HTH
Normal smart pointers, like std::auto_ptr, are not safe to use in STL containers, due to ownership being moved around when the STL assigns instances of smart pointers to each other as it copies data around internally. You need to use something like boost::shared_ptr instead, which internally implements reference counting to ensure an object stays alive no matter how many smart pointer instances refer to it. If you are writing your own smart pointer types, then you need to implement similar reference counting.
I've found this on Microsoft pages:
std::shared_ptr<base> sp0(new derived);
std::shared_ptr<derived> sp1 =
std::dynamic_pointer_cast<derived>(sp0);

What is the best way to implement smart pointers in C++?

I've been evaluating various smart pointer implementations (wow, there are a LOT out there) and it seems to me that most of them can be categorized into two broad classifications:
1) This category uses inheritance on the objects referenced so that they have reference counts and usually up() and down() (or their equivalents) implemented. IE, to use the smart pointer, the objects you're pointing at must inherit from some class the ref implementation provides.
2) This category uses a secondary object to hold the reference counts. For example, instead of pointing the smart pointer right at an object, it actually points at this meta data object... Who has a reference count and up() and down() implementations (and who usually provides a mechanism for the pointer to get at the actual object being pointed to, so that the smart pointer can properly implement operator ->()).
Now, 1 has the downside that it forces all of the objects you'd like to reference count to inherit from a common ancestor, and this means that you cannot use this to reference count objects that you don't have control over the source code to.
2 has the problem that since the count is stored in another object, if you ever have a situation that a pointer to an existing reference counted object is being converted into a reference, you probably have a bug (I.E., since the count is not in the actual object, there is no way for the new reference to get the count... ref to ref copy construction or assignment is fine, because they can share the count object, but if you ever have to convert from a pointer, you're totally hosed)...
Now, as I understand it, boost::shared_pointer uses mechanism 2, or something like it... That said, I can't quite make up my mind which is worse! I have only ever used mechanism 1, in production code... Does anyone have experience with both styles? Or perhaps there is another way thats better than both of these?
"What is the best way to implement smart pointers in C++"
Don't! Use an existing, well tested smart pointer, such as boost::shared_ptr or std::tr1::shared_ptr (std::unique_ptr and std::shared_ptr with C++ 11)
If you have to, then remember to:
use safe-bool idiom
provide an operator->
provide the strong exception guarantee
document the exception requirements your class makes on the deleter
use copy-modify-swap where possible to implement the strong exception guarantee
document whether you handle multithreading correctly
write extensive unit tests
implement conversion-to-base in such a way that it will delete on the derived pointer type (policied smart pointers / dynamic deleter smart pointers)
support getting access to raw pointer
consider cost/benifit of providing weak pointers to break cycles
provide appropriate casting operators for your smart pointers
make your constructor templated to handle constructing base pointer from derived.
And don't forget anything I may have forgotten in the above incomplete list.
Just to supply a different view to the ubiquitous Boost answer (even though it is the right answer for many uses), take a look at Loki's implementation of smart pointers. For a discourse on the design philosophy, the original creator of Loki wrote the book Modern C++ Design.
I've been using boost::shared_ptr for several years now and while you are right about the downside (no assignment via pointer possible), I think it was definitely worth it because of the huge amount of pointer-related bugs it saved me from.
In my homebrew game engine I've replaced normal pointers with shared_ptr as much as possible. The performance hit this causes is actually not so bad if you are calling most functions by reference so that the compiler does not have to create too many temporary shared_ptr instances.
Boost also has an intrusive pointer (like solution 1), that doesn't require inheriting from anything. It does require changing the pointer to class to store the reference count and provide appropriate member functions. I've used this in cases where memory efficiency was important, and didn't want the overhead of another object for each shared pointer used.
Example:
class Event {
public:
typedef boost::intrusive_ptr<Event> Ptr;
void addRef();
unsigned release();
\\ ...
private:
unsigned fRefCount;
};
inline void Event::addRef()
{
fRefCount++;
}
inline unsigned Event::release(){
fRefCount--;
return fRefCount;
}
inline void intrusive_ptr_add_ref(Event* e)
{
e->addRef();
}
inline void intrusive_ptr_release(Event* e)
{
if (e->release() == 0)
delete e;
}
The Ptr typedef is used so that I can easily switcth between boost::shared_ptr<> and boost::intrusive_ptr<> without changing any client code
If you stick with the ones that are in the standard library you will be fine.
Though there are a few other types than the ones you specified.
Shared: Where the ownership is shared between multiple objects
Owned: Where one object owns the object but transfer is allowed.
Unmovable: Where one object owns the object and it can not be transferred.
The standard library has:
std::auto_ptr
Boost has a couple more than have been adapted by tr1 (next version of the standard)
std::tr1::shared_ptr
std::tr1::weak_ptr
And those still in boost (which in relatively is a must have anyway) that hopefully make it into tr2.
boost::scoped_ptr
boost::scoped_array
boost::shared_array
boost::intrusive_ptr
See:
Smart Pointers: Or who owns you baby?
It seems to me this question is kind of like asking "Which is the best sort algorithm?" There is no one answer, it depends on your circumstances.
For my own purposes, I'm using your type 1. I don't have access to the TR1 library. I do have complete control over all the classes I need to have shared pointers to. The additional memory and time efficiency of type 1 might be pretty slight, but memory usage and speed are big issues for my code, so type 1 was a slam dunk.
On the other hand, for anyone who can use TR1, I'd think the type 2 std::tr1::shared_ptr class would be a sensible default choice, to be used whenever there isn't some pressing reason not to use it.
The problem with 2 can be worked around. Boost offers boost::shared_from_this for this same reason. In practice, it's not a big problem.
But the reason they went with your option #2 is that it can be used in all cases. Relying on inheritance isn't always an option, and then you're left with a smart pointer you can't use for half your code.
I'd have to say #2 is best, simply because it can be used in any circumstances.
Our project uses smart pointers extensively. In the beginning there was uncertainty about which pointer to use, and so one of the main authors chose an intrusive pointer in his module and the other a non-intrusive version.
In general, the differences between the two pointer types were not significant. The only exception being that early versions of our non-intrusive pointer implicitly converted from a raw pointer and this can easily lead to memory problems if the pointers are used incorrectly:
void doSomething (NIPtr<int> const &);
void foo () {
NIPtr<int> i = new int;
int & j = *i;
doSomething (&j); // Ooops - owned by two pointers! :(
}
A while ago, some refactoring resulted in some parts of the code being merged, and so a choice had to be made about which pointer type to use. The non-intrusive pointer now had the converting constructor declared as explicit and so it was decided to go with the intrusive pointer to save on the amount of code change that was required.
To our great surprise one thing we did notice was that we had an immediate performance improvement by using the intrusive pointer. We did not put much research into this, and just assumed that the difference was the cost of maintaining the count object. It is possible that other implementations of non-intrusive shared pointer have solved this problem by now.
What you are talking about are intrusive and non-intrusive smart pointers. Boost has both. boost::intrusive_ptr calls a function to decrease and increase the reference count of your object, everytime it needs to change the reference count. It's not calling member functions, but free functions. So it allows managing objects without the need to change the definition of their types. And as you say, boost::shared_ptr is non-intrusive, your category 2.
I have an answer explaining intrusive_ptr: Making shared_ptr not use delete. In short, you use it if you have an object that has already reference counting, or need (as you explain) an object that is already referenced to be owned by an intrusive_ptr.