#include <iostream>
#include <vector>
#include <cassert>
class a_class
{
public:
int num_IN;
a_class():num_IN(0){}
a_class(a_class const & origin){/*Initialise();*/} //if not called here, error occurs
void Initialise(){num_IN =5;}
};
int main ()
{
std::vector <a_class> the_vector;
for(int q=0; q < 30; q++)
{
the_vector.push_back(a_class());
the_vector[q].Initialise();
assert(5 == the_vector[q].num_IN); //no problem here
}
for(int q=0; q < 30; q++)
assert(the_vector[q].num_IN == 5); //assertion fails
}
I don't understand the difference between calling this from outside vs. inside the CC. I also don't know why it should cause a problem in any case.
std::vector
may reallocate the buffer it uses if it's size outgrows it, in which case it has to copy the old elements over to the new buffer. If you don't have a proper copy constructor that copies num_IN
over, the old value is lost.
Fix this by providing a proper copy constructor:
a_class(a_class const & origin) : num_IN(origin.num_IN) {}
In the code posted the copy constructor isn't even needed - if you don't provide one the compiler will generate a suitable one here.
The std::vector
class may have to reallocate the underlying dynamic array when you are repeatedly calling push_back()
to append new elements. The usual strategy is for std::vector
to increase the size of the underlying buffer by a factor, possibly a factor of 2
.
When this reallocation does occur, the copy constructor (or the move constructor if you've defined one and are using c++0x
) is called to copy the vector's elements from the old buffer to the new one.
Your copy constructor is not actually copying properly, you should be assigning the num_IN
parameter:
a_class(a_class const& src): num_IN(src.num_IN) {}
Typically, with STL
containers, the data types stored should obey the "rule of three" in that the constructor, copy constructor, assignment operator and destructor all work together robustly.
With move semantics in c++0x
I guess this should be extended to the "rule of five" in that you should also consider properly defined move constructors and move assignment operators.
The problem is because of the push_back
, your vector reallocates the memory in the first for
loop whenever vector's size
increases beyond its capacity
. During this reallocation vector
copies the objects already present in it by invoking the copy constructor . Since your copy constructor is not correct (You are not doing anything there), the initialized value is not carried over during reallocation.
Your copy constructor isn't doing anything. It should be saying num_IN = origin.num_IN;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With