A vector in a struct - best approach? C++

36,975

Solution 1

You can write it like this without the typedef:

struct Region 
{
    bool hasPoly;
    long size1; 
    long size2;
    long size3;
    long size4;
    long size5;
    long size6;
    long meshRef;
    std::vector<int> PVS;
}; // no typedef required

To answer your questions:

Is the vector in this declaration valid

Yes, it is.

or would it make more sense to do a pointer to a vector.

No, probably not. If you did then you would have to implement copy constructor, assignment operator and destructor for the copy behavior. You would end up with the same but it would be extra work and potentially introduce bugs.

In the case of a pointer to a vector, do I need to allocate a new vector. How would I accomplish this?

You would need to implement the copy constructor, the copy assignment operator and the destructor:

// Copy constructor
Region(const Region & rhs) :
    hasPoly(rhs.hasPoly),
    // ... copy other members just like hasPoly above, except for PVS below:
    PVS(new std::vector<int>(*rhs.PVS))
{
}

// Copy assignment operator
Region & operator=(const Region & rhs)
{
    if (this != &rhs)
    {
         hasPoly = rhs.hasPoly;
         // ... copy all fields like hasPoly above, except for PVS below:

         delete PVS;
        PVS = new std::vector<int>(*rhs.PVS);
    }
    return *this;
}

// Destructor
Region::~Region()
{
    delete PVS;
}

Bottom line: your code is fine. You don't need to change it.

EDIT: Fix assignment operator: check for comparison against this and return *this.

Solution 2

It makes complete sense to do that and you don't need new in any respect, unless you actually want to alias a separate vector. In addition, you don't need any typedef stuff going on here.

Solution 3

It depends on how you use it.

If you want to copy the vector and data when copying the Region struct, then leave it as a non-pointer.

If you don't want it copied over, then you will want some sort of pointer to a vector.

If you use a pointer to a vector, you should be very careful about allocation/deallocation exception safety. If you can't scope your allocation in an exception safe way, then you'll leave a potential for memory leaks.

A couple options are:

  • Make sure that the code that allocates the vector (and uses the Region) also deallocates the vector, and is itself exception safe. This would require the Region to only exist inside that code's scope.
    You could do this by simply allocating the vector on the stack, and pass that to the pointer in the Region. Then make sure you never return a Region object above that stack frame.
  • You could also use some sort of smart pointer -> vector in your Region.

Solution 4

The vector is fine. Be aware that if you copy this struct, then the vector will be copied with it. So in code with particular performance constraints, treat this struct the same way that you'd treat any other expensive-to-copy type.

In production code, some people would prefer you to use the class keyword rather than the struct keyword to define this class, since the vector member makes it non-POD. If you're the author of your own style guide there's nothing to worry about.

The typedef is wrong, though, just write struct Region { stuff };

Share:
36,975
Satchmo Brown
Author by

Satchmo Brown

Updated on July 09, 2022

Comments

  • Satchmo Brown
    Satchmo Brown almost 2 years

    I am trying to include a vector in my struct.

    Here is my struct:

    struct Region 
    {
        bool hasPoly;
        long size1; 
        long size2;
        long size3;
        long size4;
        long size5;
        long size6;
        //Mesh* meshRef; // the mesh with the polygons for this region
        long meshRef;
        std::vector<int> PVS;
    } typedef Region;
    

    Is the vector in this declaration valid or would it make more sense to do a pointer to a vector. In the case of a pointer to a vector, do I need to allocate a new vector. How would I accomplish this?

    Thanks!

    Edit: The problem is that it ends up causing an error that points to xmemory.h, a file included with the MSVC++ platform.

        void construct(pointer _Ptr, _Ty&& _Val)
            {   // construct object at _Ptr with value _Val
            ::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val)); // this is the line
             }
    

    Interestingly, it does not happen if I allocate it outside of the struct and simply in the function I use. Any ideas?

  • Satchmo Brown
    Satchmo Brown almost 13 years
    See the edit for the problem that is happening. Sorry. new to this site :)
  • Merlyn Morgan-Graham
    Merlyn Morgan-Graham almost 13 years
    +1. Big three usually calls for implementing copy-and-swap, too: stackoverflow.com/questions/3279543/…