I want to turn this:
into a vector with a dynamic amount of members.Code:User_laser *laser = new User_Laser(Ship,Baddy)
how would I do this?
cheers
DW
Printable View
I want to turn this:
into a vector with a dynamic amount of members.Code:User_laser *laser = new User_Laser(Ship,Baddy)
how would I do this?
cheers
DW
std::vector<SomeDatatype> SomeVectorName(InitialSize);
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
and when I add to itCode:std::vector<User_Laser> *laser(1);
what would I do?
also, how do I pass this to a function?
cheers
DW
Does that help explain it at all?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)
{
}
>>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);
Going along that train of thought, you might want to look into std::auto_ptr for automatic cleanup.Quote:
Originally Posted by Hunter2
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:Quote:
Originally Posted by Death_Wraith
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.
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];Quote:
Originally Posted by Death_Wraith
or, if you wanted to free them all you could do something like:
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.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);
}
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
see Hunter2's and MrWizard's earlier posts for other versions.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);
how do i set the length to 0 off the start? I creat it as such
and if I goCode:std::vector<User_Laser*> laser;
temp = 948574 or somthingCode:temp = laser.size();
how do I fix this?
cheers
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();
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 Hunter2
-------------------------------------
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 MrWizard
-------------------------------------
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 Death_Wraith
-------------------------------------
No,Quote:
Originally Posted by elad
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);
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.Code:vector<int> v(5, 0);
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
This shouln't be necessary.Quote:
Originally Posted by elad
If that code doesn't output 0, then something is wrong with your standard library implementation or installation.Code:#include <iostream>
#include <vector>
class DummyClass
{
};
int main()
{
std::vector<DummyClass> myVec;
std::cout << myVec.size() << std::endl;
}
-------------------------------------
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.
Jlou, that first quote is from Hunter2.
Thanks... all fixed. That'll teach me to try to quote four different posts at the same time. :)Quote:
Originally Posted by swoopy
Alright, I'm new to classes, and C++ in general, so what is this Copy thing everyone keeps talking about?
Also, ya I do want to use pointers, I find them *normaly* esier too work with!Quote:
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.
I fixed that size, thing, but this code still doesn't work. andy ideas?
it raises exceptions here:Code:std::vector<User_Laser*> laser; //this is globaly declared
...
// fires a regular shot
if (keys.laser == true)
{
laser.push_back(new User_Laser(User)); //makes new laser
laser[laser.size()]->y1=User->y1;
laser[laser.size()]->x1 = User->x1 + User->Ship_Sprite->Width / 2;
}
Again: //erases all obsolete lasers
b=0;
temp = laser.size();
for(b = 0; b <= laser.size(); b++)
{
if(laser[b]->Obsolete == true)
{
delete laser[b];
laser.erase(laser.begin() + b);
goto Again;
}
}
for(int x = 0; x<= laser.size(); x++)
{
laser[x]->regShot();
laser[x]->Collision(Baddy, laser); //check for collision between the laser and *a* baddy
}
for(int a=0; a<= laser.size(); a++)
{
laser[a]->Collision(Baddy, laser); //check for collision between the laser and *a* baddy
if(laser[a]->y1 <= 0)
{
laser[a]->Obsolete = true;
}
}
CheersCode:if(laser[b]->Obsolete == true)
You still haven't learnt have you:
By letting 'b' equal laser.size(), you're overstepping the vector bounds. Same problem, different thread. Change it to this:Code:for(b = 0; b <= laser.size(); b++)
{
Code:for(b = 0; b < laser.size(); b++)
{
>>laser[laser.size()]->y1=User->y1;
That's also overstepping the bounds. The last element in laser would be at (laser.size() - 1). But even better, you should probably use laser.back()->y1 for the sake of betterness.
Good point Hunter.
I think Death_Wraith needs a 101 in arrays.
Or more generally:Code:char array[5];
array[5]=5; //Access violation, overstepping array bounds
array[0]; //First element in array
array[4]; //Last element in array
Code:char array[SIZE];
char array[0]; //First element
char array[SIZE-1]; //Last element
>>I think Death_Wraith needs a 101 in arrays.
lol......ya....myb....i have to admit reading back, i was being kinda dumb! now i just feel dumb....I have to admit, I didn't relize that the vectors were like arrays! Stupid me! well thx guys, i'll try that 2night!
cheers
DW
*please don't hurt meeeee...... :D :confused: :p ;) :eek: :mad: :) :cool: :rolleyes: *
I'm just glad you know now.:)
Well I *do* know now, but I still have one *last* (hopefully) question:
that code doesn't work. even with
Code:b < laser.Size();
do I need to do somthing else before i can use this for loop? Because the vector is declared, its size should be 0 right? so this for loop should go from b = 0, b< 0, and nothing should happen, but it still raises exceptions when b= 0, or am i missing the point again? :confused: :eek:
Code:for(b = 0; b < laser.size(); b++)
{
if(laser[b]->Obsolete == true)
{
delete laser[b];
laser.erase(laser.begin() + b);
goto Again;
}
}
and temp still = 92 for some reason. no matter what I do. What gives with this?
cheers,
DW
If it raises an exception here, maybe you're trying to access the vector before it's initialized. Check for logic flaws in the program flow.Quote:
but it still raises exceptions when b= 0
> laser[laser.size()]->y1=User->y1;
> laser[laser.size()]->x1 = User->x1 + User->Ship_Sprite->Width / 2;
You did fix these lines as Hunter2 showed?
well thats what I thought, but the flows I think.Quote:
Originally Posted by bennyandthejets
Its declared globaly, athe top of my code, then in the game loop is where its used. i'll play around with it too day, maybe see if I can put it in the form load.
>>goto Again;
*screams and falls dead to the floor* :D Be very very sure that you're not screwing anything up on that line.
>>If it raises an exception here, maybe you're trying to access the vector before it's initialized.
It shouldn't, the loop won't even run if size() is 0. Unless, as swoopy mentioned, something before that line is causing the error.
aye i know i know! Thats the only way i could think out itQuote:
Originally Posted by Hunter2
thats what I thought... well like I said, i'll try to fix that 2dayQuote:
Originally Posted by Hunter2
I don't really see why you need to have a vector of pointers to lasers, rather than a simple vector of lasers. If you really need a vector of pointers, consider a vector of boost::shared_pointers at least. In addition erase() is an expensive operation for a vector, but pop_back() is very cheap. Thus we can have a much faster version to remove lasers so long as we don't preserve order.
Note that you save even more time if rather than have an Obsolete field you simply remove a laser from the list every time you would normally set Obsolete to true.Code:typedef std::vector<User_Laser> vlaser_t;
vlaser_t lasers;
...
// fires a regular shot
if (keys.laser == true)
{
User_Laser tmp(User);
tmp.y1 = User->y1; // User_Lasers ctor should probably do this
tmp.x1 = User->x1 + User->Ship_Sprite->Width / 2;
laser.push_back(tmp); //makes new laser
}
for(vlaser_t::size_type i=0;i < lasers.size();) {
if(lasers[i].Obsolete) {
std::swap(lasers[i],lasers.back());
lasers.pop_back();
} else ++i;
}
>>I don't really see why you need to have a vector of pointers to lasers, rather than a simple vector of lasers.
Depending on the class implementation, you might.
>>std::swap(lasers[i],lasers.back());
Won't that only work if laser has a suitable operator= defined?
While we're talking about erase-efficiency, why not use a std::list if you're just looping through the lasers?
K this is how my game works:Quote:
Originally Posted by Hunter2
if you pressed space bar, creat a new instace of the class User_Laser
regardless of the first condition (space bar pressed) loop trought all the lasers and perform collision detection.
then loop through all the lasers again, but this time check if any of the have hit anything or are off the screen. If either is the case, delete this laser, then reset the counter(the goto) and go through the loop again, checking for obsolete lasers. I've noticed that this is *rather* memory intensive tho! I need to find a new way, but for the moment, this is what i'm doing.
Alright, can I use this with my current code? All that does is swap the laser[i] with the last one, the remove the last one right?Quote:
Originally Posted by grib
Also, i could only get my vectors to work if I started my loop at, get this, 92. WTH? Whacked stuff
Thx for the help
Cheers
DW
>>does pop_back erase the last member or what?
Yes.
Can't you loop just once?Quote:
regardless of the first condition (space bar pressed) loop trought all the lasers and perform collision detection.
then loop through all the lasers again, but this time check if any of the have hit anything or are off the screen. If either is the case, delete this laser, then reset the counter(the goto) and go through the loop again, checking for obsolete lasers. I've noticed that this is *rather* memory intensive tho! I need to find a new way, but for the moment, this is what i'm doing.
Loop through - for each one: do collision detection; then check for hit or offscreen; if either, then delete it.
Why do you need to reset the counter? Can't you just keep going through the loop (decrease the counter by 1 and keep going)?
And even if you do need to, just set b = 0 or whatever it is.
It does sound like a list is more what you want than a vector. A vector is more appropriate if you need random access, meaning you have a laser that you know is at position 12, and you need to access it. (Note that even if you need that, a map might be better than a vector.)
Here is some example code for a list:I used User_Laser objects instead of pointers because that is easier for me. Notice the last function - EraseObsoleteLasers. It allows you to check for obsolete lasers and erase them from the list. No need to go through the list more than once, and certainly no need for a goto. Similar code can be used for vectors (NOT the same, though, since an erase in a vector invalidates the end iterator I cached).Code:#include <iostream>
#include <list>
class User_Laser
{
int data;
public:
User_Laser(int start) : data(start) { }
bool Obsolete() { return ++data > 5; }
};
void FireShot(std::list<User_Laser>& laserList, int start);
void EraseObsoleteLasers(std::list<User_Laser>& laserList);
int main()
{
std::list<User_Laser> laserList;
// fire some shots
FireShot(laserList, 3);
std::cout << "After fire: " << laserList.size() << std::endl;
EraseObsoleteLasers(laserList);
std::cout << "After erase: " << laserList.size() << std::endl;
FireShot(laserList, 0);
std::cout << "After fire: " << laserList.size() << std::endl;
EraseObsoleteLasers(laserList);
std::cout << "After erase: " << laserList.size() << std::endl;
FireShot(laserList, 2);
std::cout << "After fire: " << laserList.size() << std::endl;
EraseObsoleteLasers(laserList);
std::cout << "After erase: " << laserList.size() << std::endl;
while (!laserList.empty())
{
EraseObsoleteLasers(laserList);
}
std::cout << "At the end: " << laserList.size() << std::endl;
}
void FireShot(std::list<User_Laser>& laserList, int start)
{
laserList.push_back(User_Laser(start));
}
void EraseObsoleteLasers(std::list<User_Laser>& laserList)
{
std::list<User_Laser>::iterator currentLaser = laserList.begin();
std::list<User_Laser>::iterator pastEndLaser = laserList.end();
while (currentLaser != pastEndLaser)
{
if (currentLaser->Obsolete())
currentLaser = laserList.erase(currentLaser);
else
++currentLaser;
}
}
So, how much faster is a list than a vector? Is it worth it?
I don't know how complicated your code is, or how big your data structure will be during normal program operation, so it's hard to say. Chances are that you would never notice a difference.
It's more about choosing the most appropriate data structure for your needs. In this case, since you will be removing from the middle, a list would be more appropriate because it doesn't have the overhead of copying all the data after the removed object.
When you erase something from a vector, all of the values after that entry must be moved over one spot in memory using copying. For a list, only a couple of internal pointers need to be updated. If your vector only has 5-10 User_Laser's in it, you won't notice the speed difference. If that is the case, then it would be perfectly fine for you to decide that vectors are better for you because of other reasons (like being more familiar with them or not wanting to learn about lists now that you've been working on vectors).
Ah well, the vector has, at times, up wards of 20+ objects. Pretty much its how fast you can hit the space + control key! Also, I notice that it runs kinda slow... I have that code I posted running 3 times, one for missiles, one for laser, and one for baddy lasers. So do you figure that thats making the difference?
Cheers
DW
No, probably not. If anything, it's going to be either graphics or the constructor or hit detection or something else that's slowing it down, not the vector/list. Looping through a list or vector isn't slow at all, the only reason you would consider the number of elements is that with more, each loop has to keep going longer - which isn't normally a problem - or in the case of a vector, it'll take longer to do insert/erase operations in the middle/beginning of the vector. In the case of a list, it takes the same amount of time inserting/erasing from any part of the list, no matter how many elements there are.
Alright. Well I guess i'll keep with the vectors, as i'm used to working with them atm. I'll see if I can speed up the res of my code though...
Effective STL
Good book.
gg
Awsome, thx guys. Also, how do I do this, but with vectors?
and how do I compare it against an int, such as,Code:std::list<User_Laser>::iterator currentLaser = laserList.begin();
std::list<User_Laser>::iterator pastEndLaser = laserList.end();
cheersCode:for(i=currentLaser ; i < laser.size();i++
{
}
>Also, how do I do this, but with vectors?
Change the word list to vector. :)
>and how do I compare it against an int
You mean how do you extract an integral index from an iterator? By subtracting the current iterator from the first iterator in the sequence. The result is the distance between the two iterators in number of items:
Code:for (int i = currentLaser - laser.begin(); i < laser.size(); i++) {
...
}
Unless you need the integer index for a specific reason, I would just use the iterators to access the data. The code compiles whether it is a list or a vector, so if you use the iterators it makes it easier to change your mind later.
There is one important note that I briefly referred to above. Erasing from a vector invalidates the iterators after it, so you can't cache the end() iterator. Here is that function for a vector:Code:void EraseObsoleteLasers(std::vector<User_Laser>& laserList)
{
std::vector<User_Laser>::iterator currentLaser = laserList.begin();
while (currentLaser != laserList.end())
{
if (currentLaser->Obsolete())
currentLaser = laserList.erase(currentLaser);
else
++currentLaser;
}
}
Hmmm, I couldn't get that too work, so I tried somthing else, and that didn't work either. I declare my iterator up top, globlay,
then I use it belowCode:std::vector<User_Laser*>::iterator currentLaser = laser.begin();
but I get this error when I compileCode:while (currentLaser != laser.end())
{
if (currentLaser->Obsolete)
currentLaser = laser.erase(currentLaser);
else
currentLaser++;
}
with the highlighting on theCode:[C++ Error] Unit1.cpp(127): E2288 Pointer to structure required on left side of -> or ->*
partCode:if (currentLaser->Obsolete)
cheers
DW
Since your vector holds pointers (my example did not), then you must add one more dereference to your code:Also, setting the iterator globally is not a good idea, because the iterator returned from begin will change when you add things to the vector. It is better to set it in the function just before you use it. And finally, ++currentLaser is preferred over currentLaser++.Code:void EraseObsoleteLasers(std::vector<User_Laser*>& laserList)
{
std::vector<User_Laser*>::iterator currentLaser = laserList.begin();
while (currentLaser != laserList.end())
{
if ((*currentLaser)->Obsolete())
currentLaser = laserList.erase(currentLaser);
else
++currentLaser;
}
}
Wow...I must have reached some record for most help needed! lol.
thx for the quick answers guys, definatly I really appreciate it. I tried what you suggested jlou, but I get a "Call to non-function" at this line :
Oh... and why is ++i preffered over i++ ?Code:if ((*currentLaser)->Obsolete())
cheers
DW
Sorry, I forgot to change that. My example Obsolete was a function, so I used the parentheses. Your Obsolete is a bool variable, so you should remove the parentheses:
if ((*currentLaser)->Obsolete)
The reason ++i is preferred over i++ is that in general, when you use i++, the code must make a copy of i, then increment it, then return the copy. Even if you don't use the returned value, the code that figures it out might still be run. When you use ++i, i is incremented first, and then returned without a copy being made. Since you are ignoring the return value, you don't care what is returned, the pre-incremented value or the post-incremented value. Since you don't care, it is better to go with the one that won't require an unnecessary copy. It is possible that the extra copy is optimized away, but I wouldn't count on it and there is no reason to since there is really no difference to you in writing one or the other. This isn't a big deal, just another suggested good habit.
>>Wow...I must have reached some record for most help needed! lol.
No, nobody has surpassed me yet :p
Funny, because I think I remember asking both those questions above before... heh... I'm still the n00b m4st4!
Damn! O well.... :DQuote:
Originally Posted by Hunter2
Alright, I've been trying that code, and frankly, I feel really stupid and frustrated now! Every time, at this line
if raises an exception. Any help would be great, as this project is due real soo!:mad:Code:if ((*currentLaser)->Obsolete)
Cheers
DW
Since you are holding pointers in your vector, one possible reason you are getting an exception on that line is if the pointer stored in the vector is invalid - meaning it is null or has already been deleted or was never initialized. That is one of the reasons I kept advising you to not use pointers. ;)
Another note, since you are holding pointers in your vector, make sure you are deleting the memory correctly. In my example Erase function, I did not free any memory because my original example held objects instead of pointers. The modified example must be updated to delete the memory at (*currentLaser) before erasing it from the list, or else you will have a memory leak.
[QUOTE=jlou]Since you are holding pointers in your vector, one possible reason you are getting an exception on that line is if the pointer stored in the vector is invalid - meaning it is null or has already been deleted or was never initialized. That is one of the reasons I kept advising you to not use pointers. ;)QUOTE]
Ah...well...to late now I guess. How do I test if the vector is null? I've tried if(laserVect.empty()) then ...... but nothing really happens. It doesn't seem to want to work. Any ideas? thx again
You want to test if the pointer value held at the position represented by the iterator is null. Here is one example in red (make sure you adapt it appropriately to your needs). I also added an example of deleting memory in blue. This code removes and deletes the memory of Obsolete User_Lasers AND removes null pointers.Code:void EraseObsoleteLasers(std::vector<User_Laser*>& laserList)
{
std::vector<User_Laser*>::iterator currentLaser = laserList.begin();
while (currentLaser != laserList.end())
{
if ((*currentLaser) == 0 || (*currentLaser)->Obsolete)
{
User_Laser* laserToDelete = (*currentLaser);
currentLaser = laserList.erase(currentLaser);
delete laserToDelete;
}
else
{
++currentLaser;
}
}
}
Well.. I tired this word for word, and still the same problem.Quote:
Originally Posted by jlou
So...I experimented a bit.
I tried with the for loops again. Exception. Alright....I tried setting "temp = laser.size()" and the size of a just created laser, well apparently varies between -600002 and 3965?!!?!
:confused: Okay I said, lets make the loop counter (b =) to temp. and it works. Not very well, because I must be doing somthing wrong with the size, because you have to make, ~100 lasers before they start to show, but at least it works. Every Vector sizer(eg: temp) is different. And only one starts at 0. So i'm assuming that this isn't normal/right aka: whats causing my problems. I also tried testing for the laser.empty() property, and that didn't really work. Soo....the point to this ramble is, any idea why this is so whacked? Because when I go currentLaser-> , the auto complete thingy pops up, but not when I do, (*currentLaser)->.......soo......any help would be very much appreciated, because, I quite frankly, have no idea what i'm doing when it comes to vectors( and quite possibly, c++! :D )
Cheers
The best thing I can say is to post your current code.
I have no idea why you are getting weird sizes, but earlier when you had similar problems you said you fixed it. Maybe you made the same mistake again? Post what you have so that we can see if you are implementing these suggestions correctly.
Ah, I *thought* I fixed it! Turns out the others were still wierd. I"ll post the code, but be warned, its a lot of code! I"ll double post the code below
Main game loop
functions in header file,Code:void __fastcall TForm1::GameLoop(TObject*, bool &done)
{
int b,temp;
//checks if you've killed everything
if (dead_count == 21)
{
Application->MessageBoxA("You won!","Well done, you stopped the invasion", MB_OK);
Application->Terminate();
}
//Key presses are acted upon here
if (keys.right == true)
{
User->MoveRight(); //right key pressed, move right
}
if (keys.left == true)
{
User->MoveLeft(); //left key pressed, move left
}
if (keys.up == true)
{
User->MoveUp(); //up key pressed. move up
}
if (keys.down == true)
{
User->MoveDown(); // down key pressed. move down
}
// fires a regular laser shot
if (keys.laser == true)
{
//dynamicly allocates memory on the heap; User(the ship) is passed to the constructor
//so the x1 && y1 coords are the same as the users
laser.push_back(new User_Laser(User));
//keys.laser = false; //un-presses the space bar so we can't have insane firing speeds =)
}
// fires a regular missile shot
if (keys.missile == true)
{
//dynamicly allocates memory on the heap; User(the ship) is passed to the constructor
//so the x1 && y1 coords are the same as the users
missile.push_back(new User_missile(User));
keys.missile = false;//un-presses the control key so we can't have insane firing speeds =)
}
//deletes any unused lasers, then moves the rest
EraseObsoleteLasers(laser,Baddy);
EraseObsoleteMissiles(missile, Baddy);
//draws to the form. See the "Draw" file for further info
Draw(BackBuffer, User, Baddy, ClientRect, BackGround, laser, missile, Health, bdy_laser, bdyDraw, FirstMissile , FirstLaser);
done = false;
}
Code:#include <vector.h>
#include "fire.h"
#include "Unit1.h"
using namespace std;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void EraseObsoleteLasers(std::vector<User_Laser*>& laserVect, Enemy *Baddy[3][7])
{
std::vector<User_Laser*>::iterator currentLaser = laserVect.begin();
int b;
while (currentLaser < laserVect.end())
{
if ((*currentLaser) == 0 || (*currentLaser)->Obsolete)
{
User_Laser* laserToDelete = (*currentLaser);
currentLaser = laserVect.erase(currentLaser);
delete laserToDelete;
}
else
{
++b;
(*currentLaser)->regShot();
(*currentLaser)->Collision(Baddy, laserVect, b); //check for collision between the laser and *a* baddy
++currentLaser;
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void EraseObsoleteMissiles(std::vector<User_missile*>& missileVect, Enemy *Baddy[3][7])
{
std::vector<User_missile*>::iterator currentMissile = missileVect.begin();
int b;
while (currentMissile != missileVect.end())
{
if ((*currentMissile)->Obsolete)
currentMissile = missileVect.erase(currentMissile);
else
{
++b;
(*currentMissile)->regShot();
//check for collision between the laser and *a* baddy
(*currentMissile)->Collision(Baddy, missileVect, b);
++currentMissile;
}
}
}
Hmmm, you have #include<vector.h> at the top of your second piece of code, but then you use the STL vector which is in <vector> without the ".h". Are you including the correct headers?
I'm not all that familiar with the specifics of C++ Builder, maybe it has a weird implementation that is causing your code to go haywire.
Is the problem still an exception at this line?Code:if ((*currentLaser)->Obsolete)
Yup, same line. About the headers, I wasn't sure what too use. A book said <vector.h> You guys were says this std namespace, and I wasn't sure what I needed, so I included both! Is this bad? Also, does the code look okay?
Cheers
Edit: Well, playing around with the code, i set laser.clear(); on the initialization, and low and behold it works! :confused: strange....regardless it works, needs some work tho.... ;) funny stuff... thanks for all the help! Also, the .h thing, which do i need?
Cheers
You should use the new header style, ie:Quote:
A book said <vector.h>
Code:#include <vector>
using namespace std;
I think <vector.h> is specific to Borland's libraries, and is a completely different library (not just the old style). The STL vector is in <vector>, which is what you need for what we've been talking about.
Strange about needing the clear(), I don't know why it wouldn't start out initialized empty properly, maybe it depends on how you declared it globally. Glad it works though.
Thx! Ya its deffinatly strange, although, i've come to expect that from c++. It's strange though, running all that code (shoot, collision, move lasers, delet obsolete laser) seems pretty slow. And its not like its that much code either!....Very strange...
CHeers, and thanks for the help
DW