views:

58

answers:

3

Hello, I'm having some trouble to find the best way to accomplish what I have in mind due to my inexperience. I have a class where I need to a vector of objects. So my first question will be:

  • is there any problem having this: vector< AnyType > container* and then on the constructor initialize it with new (and deleting it on the destructor)?

Another question is: if this vector is going to store objects, shouldn't it be more like vector< AnyTipe* > so they could be dynamically created? In that case how would I return an object from a method and how to avoid memory leaks (trying to use only STL)?

+1  A: 

Yes, you can do vector<AnyType> *container and new/delete it. Just be careful when you do subscript notation to access its elements; be sure to say (*container)[i], not container[i], or worse, *container[i], which will probably compile and lead to a crash.

When you do a vector<AnyType>, constructors/destructors are called automatically as needed. However, this approach may lead to unwanted object copying if you plan to pass objects around. Although vector<AnyType> lends itself to better syntactic sugar for the most obvious operations, I recommend vector<AnyType*> for non-primitive objects simply because it's more flexible.

Joey Adams
Thanks. But if I have vector< AnyType* > and I want to return an element do I have to do something like return new AnyType(..) using AnyType copy constructor? I believe I can't just return elements directly from the vector right?
dmessf
The vector contains pointers, those are the elements. You can use a pointer for as long as it remains valid. If the pointer points to a dynamically allocated object, then it remains valid until someone deletes it, that someone being you. So, if you're planning on deleting the object before your caller is finished using it, then you would need to return a copy of the object (or use reference-counting). If you are copying you'd normally be better off returning it by value, than creating a copy with `new` and returning a pointer. C++ simply is not Java.
Steve Jessop
+1  A: 

Don't use new and delete for anything.

Sometimes you have to, but usually you don't, so try to avoid it and see how you get on. It's hard to explain exactly how without a more concrete example, but in particular if you're doing:

SomeType *myobject = new SomeType();
... use myobject for something ...
delete myobject;
return;

Then firstly this code is leak-prone, and secondly it should be replaced with:

SomeType myobject;
... use myobject for something (replacing -> with . etc.) ...
return;

Especially don't create a vector with new - it's almost always wrong because in practice a vector almost always has one well-defined owner. That owner should have a vector variable, not a pointer-to-vector that they have to remember to delete. You wouldn't dynamically allocate an int just to be a loop counter, and you don't dynamically allocate a vector just to hold some values. In C++, all types can behave in many respects like built-in types. The issues are what lifetime you want them to have, and (sometimes) whether it's expensive to pass them by value or otherwise copy them.

shouldn't it be more like vector< AnyTipe* > so they could be dynamically created?

Only if they need to be dynamically created for some other reason, aside from just that you want to organise them in a vector. Until you hit that reason, don't look for one.

In that case how would I return an object from a method and how to avoid memory leaks (trying to use only STL)?

The standard libraries don't really provide the tools to avoid memory leaks in all common cases. If you must manage memory, I promise you that it is less effort to get hold of an implementation of shared_ptr than it is to do it right without one.

Steve Jessop
+1  A: 

is there any problem having this: vector< AnyType > *container and then on the constructor initialize it with new (and deleting it on the destructor)

No there isn't a problem. But based on that, neither is there a need to dynamically allocate the vector.

Simply make the vector a member of the class:

class foo
{
    std::vector<AnyType> container;
    ...
}

The container will be automatically constructed/destructed along with the instance of foo. Since that was your entire description of what you wanted to do, just let the compiler do the work for you.

R Samuel Klatchko