Thread: Vector Question

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    180

    Vector Question

    I want to turn this:

    Code:
    User_laser *laser = new User_Laser(Ship,Baddy)
    into a vector with a dynamic amount of members.

    how would I do this?

    cheers

    DW

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    std::vector<SomeDatatype> SomeVectorName(InitialSize);
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    When I redim the vector from lets say, laser[5] to laser[6] and I want to add a new User_Laser variable, how would I do this?

    so the intiatial initialization would be

    Code:
     	std::vector<User_Laser> *laser(1);
    and when I add to it

    what would I do?

    also, how do I pass this to a function?

    cheers

    DW

  4. #4
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Code:
    {
        // ...
    
        std::vector<User_laser> myLaserVector; // create and initialize vector
    
        User_laser myLaser(Ship, Baddy);
    
        myLaserVector.push_back(myLaser); // add myLaser to the vector
                                          // this dynamically grows the vector to a size of one
    
        // push 5 more User_laser objects onto the vector.
        for (int i = 0; i < 5; i++)
            myLaserVector.push_back(User_laser(Ship, Baddy));
    
        // now myLaserVector has a size of 6.
    
        // pass the vector to a function.
        myFunc(myUserVector);
    
        // ...
    }
    
    // myFunc is a function that takes a vector.  Remove the const
    // if you need to modify the vector in the function.
    void myFunc(const std::vector<User_laser>& passedInLaserVector)
    {
    }
    Does that help explain it at all?

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>myLaserVector.push_back(myLaser);
    Depending on how foolproof the class is about copy constructors/destructors etc, that might be a bad idea. When dealing with objects of classes, it's easier just to create a vector of (SomeClass*)'s and use new to create objects and push the pointers onto the vector. Then, just remember to delete an element of the vector before erase()ing it.

    Code:
    std::vector<MyClass*> vect;
    vect.push_back(new MyClass(45, "aabcd"));
     
    ...
     
    delete vect[someIndex];
    vect.erase(vect.begin() + someIndex);
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Quote Originally Posted by Hunter2
    >>myLaserVector.push_back(myLaser);
    Depending on how foolproof the class is about copy constructors/destructors etc, that might be a bad idea. When dealing with objects of classes, it's easier just to create a vector of (SomeClass*)'s and use new to create objects and push the pointers onto the vector. Then, just remember to delete an element of the vector before erase()ing it.
    Going along that train of thought, you might want to look into std::auto_ptr for automatic cleanup.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  7. #7
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    Alright, I'm gonna have to try some of that code. Thanks for the help.

    Also, if I delete lets say vect[3] and the vect has 6 elements, so after the deletion, it only has 5, does the rest of the vector move down one, taking up the unused space.


    (dunno if this is the right code, but go with me here!)
    eg: Vect[1,2,3,4,5,6]
    vect.delete[3]
    vect no = vect[1,2,4,5,6]

    is this what happens?

    also, if I have a "newed" member, do i access it using the -> ?

    Cheers

    DW
    Last edited by Death_Wraith; 06-02-2004 at 08:41 PM.

  8. #8
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Quote Originally Posted by Death_Wraith
    Alright, I'm gonna have to try some of that code. Thanks for the help.

    Also, if I delete lets say vect[3] and the vect has 6 elements, so after the deletion, it only has 5, does the rest of the vector move down one, taking up the unused space.


    (dunno if this is the right code, but go with me here!)
    eg: Vect[1,2,3,4,5,6]
    vect.delete[3]
    vect no = vect[1,2,4,5,6]

    is this what happens?

    also, if I have a "newed" member, do i access it using the -> ?

    Cheers

    DW
    I'm assuming that's all pseudo code up there. As in, you know that won't compiler right? But yes, if you used the erase member function of vector with the appropriate parameter then it would "move down one" space. Essentially erasing that space and moving everything else forward one. Keep in mind that your memory will not be freed if you dynamically allocated it. If you had a vector v then one of the many ways to access it would be:

    v[1]->Method(); // access element at position 1 and call Method.

    You could also get an iterator and use that if you'd like. Or also the at member function of vector does bounds checking but is slower.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  9. #9
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    LOL. I'd laugh that if *did* compile, or if I tried that! How do I free a member i erased?

    cheers

  10. #10
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Quote Originally Posted by Death_Wraith
    LOL. I'd laugh that if *did* compile, or if I tried that! How do I free a member i erased?

    cheers
    delete vec[2];

    or, if you wanted to free them all you could do something like:

    Code:
    // Const iterator to walk through vector
    std::vector< Class* >::const_iterator citer;
     
    // Start at beginning and go to the end
    for( citer = vec.begin(); citer != vec.end(); ++iter )
    {
      delete (*iter);
    }
    It's a good habit to start using iterators. Even though vector's allow you random access not all STL containers do. List's for example do not, you would need to use an iterator for that. So it's easier to write generic code that could take any STL container and free it's memory using template parameters rather than write specific code.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    IF you had a vector of pointers of size 6 with the memory assigned to each pointer allocated by new and you wanted to remove an element, I believe you delete the memory for the pointer at the element first, then call the erase() function to actually "remove" (overwrite) the pointer at the element and "shift" (overwrite) the remaining elements to the left. I'd try something like this--not compiled/tested
    Code:
    //declare vector of int pointers
    vector <int *> v;
    //add six pointers to v
    for(i = 0; i < 6; ++i)
    {
    v.push_back(new int);
    //assign i to each pointer in v as it is entered
    *(v.back()) = i;
    }
     
    //delete memory where value of 3 is stored (ie, index 4) from v
    delete v[4];
     
    //v[4] is now a dangling pointer as it has no memory assigned to it
     
    //erase pointer at index 4
    vector<int *>::iterator itr = v.begin();
    for(i = 0; i < 4; ++i)
    ++itr;
    v.erase(itr);
    see Hunter2's and MrWizard's earlier posts for other versions.
    Last edited by elad; 06-03-2004 at 11:53 AM.

  12. #12
    Registered User
    Join Date
    Mar 2004
    Posts
    180
    how do i set the length to 0 off the start? I creat it as such

    Code:
    std::vector<User_Laser*> laser;
    and if I go

    Code:
    temp = laser.size();
    temp = 948574 or somthing

    how do I fix this?

    cheers

  13. #13
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    You don't have to set (increase or decrease) the size/capacity of a vector at all, if you don't want to. Each implementation of the vector class will have a default initial capacity and a default value to increase the capacity by, if necessary. You can force the issue, if you want, but it probably won't increase efficiency very much, and may hurt it.

    I believe

    vector<int> v(5);

    creates of vector of int of capacity 5 and size 0;

    and I believe

    vector<int> v(5, 0);

    creates a vector of int of capacity 5 and size 5 with each int initialized to value of 0.

    Then to force a change in size of v once initially declared using default or non default size/capacity you can use the resize() method, if you really want to.

    You might need to check to see if a vector is empty before checking the size and to reset size to 0 you would use clear() method.

    if(!v.empty())
    temp = v.size();

    v.clear();
    Last edited by elad; 06-03-2004 at 11:48 AM.

  14. #14
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Quote Originally Posted by Hunter2
    Depending on how foolproof the class is about copy constructors/destructors etc, that might be a bad idea. When dealing with objects of classes, it's easier just to create a vector of (SomeClass*)'s and use new to create objects and push the pointers onto the vector. Then, just remember to delete an element of the vector before erase()ing it.
    In my opinion, it is a better idea to make sure your copy constructor/assignment operator is correct (if it is necessary), than it is to store pointers in the vector. Obviously, if the object is big, or copying is expensive, then storing pointers is a good idea, but for a simple class I would think that avoiding the headaches of dynamically allocated memory is preferred.

    -------------------------------------
    Quote Originally Posted by MrWizard
    Going along that train of thought, you might want to look into std::auto_ptr for automatic cleanup.
    Since we are talking about storing pointers inside vectors, do not look into storing auto_ptr's inside a vector. The auto_ptr's copy semantics are not compatible with STL containers.

    -------------------------------------
    Quote Originally Posted by Death_Wraith
    how do i set the length to 0 off the start? I creat it as such
    Code:
    std::vector<User_Laser*> laser;
    temp = laser.size();
    temp = 948574 or somthing
    There is something else wrong with your code, then. The size is zero if you create the vector the way you did above, so temp should be zero.

    -------------------------------------
    Quote Originally Posted by elad
    I believe

    vector<int> v(5);

    creates of vector of int of capacity 5 and size 0;

    and I believe

    vector<int> v(5, 0);

    creates a vector of int of capacity 5 and size 5 with each int initialized to value of 0.
    No,
    Code:
    vector<int> v(5);
    creates a vector of size 5, meaning five objects are stored in the vector, all created using the default constructor (in that case all ints are 0). The capacity could be anything depending on the implementation. Also,
    Code:
    vector<int> v(5, 0);
    does the exact same thing. The vector has a size of 5, meaning five objects are stored in the vector. All five objects have the value that was given as the second argument, in this case 0. The capacity could be anything depending on the implementation.
    Quote Originally Posted by elad
    Then to force a change in size of v once initially declared using default or non default size/capacity you can use the resize() method, if you really want to.
    Yes, resize() changes the size of the vector, adding default constructed objects if the new size is larger than the old. The reserve() function changes the capacity, but you shouldn't really be worrying about capacity at this point, just let the vector implementation worry about it. If you are concerned about the speed of your program, and you know exactly how many elements you will be putting into your vector, then it might be a good idea to reserve enough space for them before you push them onto the vector.
    Quote Originally Posted by elad
    You might need to check to see if a vector is empty before checking the size and to reset size to 0 you would use clear() method.

    if(!v.empty())
    temp = v.size();
    This shouln't be necessary.
    Code:
    #include <iostream>
    #include <vector>
    
    class DummyClass
    {
    };
    
    int main()
    {
        std::vector<DummyClass> myVec;
        std::cout << myVec.size() << std::endl;
    }
    If that code doesn't output 0, then something is wrong with your standard library implementation or installation.

    -------------------------------------

    Death_Wraith, I think that it might be easier for you to store objects rather than pointers in your vector. That decision is up to you, but if your User_laser is not very big and if copying those objects is not an expensive operation, then I would recommend avoiding the hassle of new and delete. That is one of the reasons to use vector in the first place. You should of course make sure your copy constructor and operator= work, or make sure that you don't need them because the default versions are fine, but you should always do this regardless of how you use that class.
    Last edited by jlou; 06-03-2004 at 03:51 PM.

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Jlou, that first quote is from Hunter2.

Popular pages Recent additions subscribe to a feed