views:

69

answers:

3

Option 1:

class B{//};
class A
{
    public:
        void Funcs();
    private:
       std::vector<A> vecA;
};

Option2:

class B{//};
class A
{
    public:
        void Funcs();
    private:
        std::vector<A*> vecpA;
};

Which one is better, is there any guidelines?

+1  A: 

Use the vector of objects when you can. Use the vector of pointers when that's the only (reasonable) way to accomplish what you want. Beyond that, you have to deal with questions like whether the A owns the objects in vecA or only has references to objects that are owned by something else.

Jerry Coffin
+3  A: 

This is one of those things where it depends on the specific scenario. Here is an incomplete laundry list of questions to ask yourself when deciding between these different options:

  1. Is it polymorphic? I.e., do you know the exact type at compile-time, or could you have different runtime types that all inherit from the same base type. Polymorphic => POINTER.
  2. How big is this object? I.e., will constructing the object on the stack overrun my stack allocation? If it is small to moderately big, then it doesn't matter. Huge => POINTER.
  3. Do I want to ensure that only I have a copy (or that my copy is unique). Will this object be exposed to other parts of the interface. Could this lead to ambiguity of ownership in the API. If yes, then probably a pointer is not the best choice. This would be a good case for using the object directly. Overall API cleanliness => OBJECT.

If you do go with a pointer, typically you will want to use boost::unique_ptr if the class is the only owner, or boost::shared_ptr if the data may be shared across multiple objects, threads, etc. Only in rare circumstances are raw, regular C++ pointers the right way to go. It's hard to pin down what those are.

Michael Aaron Safyan
Great general write-up. Re 2), vector's don't put the contained objects on the stack - they go on the heap regardless. Another crucial factor is that growing a vector or large objects is much more costly than growing a vector of pointers to such objects. Yet another factor is the need to use specialised comparison etc functors to apply some algorithms via pointers.
Tony
@Tony, good point about #2, though FYI I was answering the more general question of when to use a pointer or just a regular member.
Michael Aaron Safyan
+1  A: 

If 'A' is not copyable and assignable, you are left with no choice but to use the pointer to 'A'.If 'A' is not copyable and assignable, you are left with no choice but to use the pointer to 'A'.

Assuming however that 'A' is copyable and assignable, then the choice would be guided by factors including but not limited to:

a) Do you really want the container / algorithms to operate on a separate copy rather than the original object (through pointer)

b) What is the performance penalty of copying?

c) Do you want to store polymorphic objects in the container using the pointer approach?

I guess RValue references of C++0x have some relief to offer in point (a) and (b) but I am not sure.

Chubsdad