I notice <vector> uses the constructor once and then uses the copy constructor for a class when creating all the other elements of a vector chain.

So, if I have:

class MyClass {
  MyClass() {
    cout << "Constructor" << endl;
  }
  ~MyClass() {
    cout << "Deconstructor" << endl;
  }
  MyClass(const MyClass& mc) {
    cout << "Copy Constructor" << endl;
  }
}

calling as a vector array (sorry, don't know of a better term!)

// in main...
vector<MyClass> mc(2);

Instead of:-
"Constructor"
"Constructor"
"Destructor"
"Destructor"

I get:
"Constructor"
"Copy Constructor"
"Copy Constructor"
"Destructor"
"Destructor"
"Destructor"

Which is fine... but I'm developing classes where each class gets a unique ID (incremented from a static int in the class) in the Constructor and it would be preferable to have the constructors called independantly. Otherwise, I end up with 'missing' IDs from the 'temporary' classes called via the vector.

The only way I can think of is to
1. Create a regular array dynamically.
2. vector<MyClass> mc(array, array+size)
3. Delete the previous array.

Is there a better way to ensure the constructor is called every time (for each allocated instance in the vector array) and not when a temporary one is being used via a copy constructor? I wish I could phrase this better, but I'm struggling to describe it and apologise for the confusion.

[edit - simpler - can I get the constructor called for each element in the vector<class> var(num_elements) when the vector array is declared? (like you would in a regular array) ]

Recommended Answers

All 5 Replies

Just start off with a blank vector and push the objects on.

class Foo
{
    // ...
}

int main()
{
    vector<Foo> container;
    for (int i = 0; i < 10; i++)
    {
        container.push_back(Foo());
    }
}
commented: Thanks for the code example as well. +0

(apologies for the delay in replying to this)

Great, thank you!

The answer to the ID problem was solved by having the copy constructor copy the ID of the temporary class to the permanent class when being pushed onto the stack.

Just one small follow-on question about using push_back.

(code edited to show 1000 push_backs)

int main()
{
    vector<Foo> container;
    for (int i = 0; i < 1000; i++)
    {
        container.push_back(Foo());
    }
}

When i=999, just for that one statement, there are 999 Destructor calls, and, I guess for the whole loop of i=0 to i=999 you'll end up with 999! (factorial) calls to constructors/destructors.

This is surely a massive performance hit, especially if classes contain allocation and de-allocation statements?

Well i ran a couple of test with i being equal 10, 100, 1000 and 10000 and it appears that there is about a 3.5 to 1 ratio with the destructor calls against constructor calls. This is the code I used to test the amount of calls used.

#include <iostream>
#include <vector>

using namespace std;

int constructorCount = 0, destructorCount = 0;

class Foo
{
public:
    Foo() { constructorCount++; }
    ~Foo() { destructorCount++; }
};

int main()
{
    vector<Foo> bar;
    for (int i = 0; i < 10000; i++)
        bar.push_back(Foo());
    cout << "constructorCount = " << constructorCount << endl;
    cout << "destructorCount = " << destructorCount << endl;
    cin.get();
    return 0;
}

> This is surely a massive performance hit, especially if classes contain allocation and de-allocation statements?
It *can* be too much overhead, but in those cases you should be storing a vector of light weight smart pointers.

int main()
{
    vector<shared_ptr<Foo> > container;

    for (int i = 0; i < 1000; i++)
        container.push_back(shared_ptr<Foo>(new Foo));
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.