C++ vectors and class constructors

Started by
2 comments, last by Zahlman 15 years, 9 months ago
So, I have a class with a constructor which assigns a random values some of its members. However, from what I can tell, when you allocate a vector of objects, it creates one object then assigns a copy of that object to every object in the vector. Perhaps some example source code will explain:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace std;

class Foo
{
public:
   Foo() : x(rand()%500) { }
   int getX() { return x; }

private:
   int x;
};

int main()
{

   srand( time(NULL) );

   Foo f[5];
   for ( int i = 0; i < 5; i++ )
   {
      cout << "x = " << f.getX() << ", ";
   }

   cout << endl;

   vector<Foo> f2(5);
   for ( int i = 0; i < f2.size(); i++ )
   {
      cout << "x = " << f2.getX() << ", ";
   }

   return 0;
}

The output of the above will be something like (obviously with randomness)

x = 214, x = 86, x = 258, x = 442, x = 391,

x = 262, x = 262, x = 262, x = 262, x = 262,

You can see that when using the vector, the constructor is only called once and then the values are copied into each element. Now, I know I can solve this by using an initialization function instead. Or perhaps by writing a copy constructor which re-randomizes the variable on copy (though I'd prefer not to do this as I feel a copy should merely copy the values, unless dealing with pointers). Is there some other method that I am overlooking or some trick to the STL vector to get what I want? Or do I just need to suck it up and use an initialization function?
Advertisement
vector<Foo> f2;f2.reserve(5);for (int i=0; i<5; i++){    f2.push_back(Foo());}
Ah, wow. I do not believe I was aware I could create a new object by just calling the class constructor like that - which is odd considering how long I've been using C++... Guess you do learn something everyday with the language from hell. I did try doing the push_back method, but assumed I would need to use pointers and call new Foo() in the push_back call. However, I really did not want to abuse pointers like that.

That's the cleanest method I've seen for this. Thanks. :)
Foo create() { return Foo(); }std::vector<foo> f;std::generate_n(std::back_inserter(f), 5, create);

This topic is closed to new replies.

Advertisement