Search code examples
c++vectorconstructordestructorpush-back

vector destroys objects but does not construct their replacements?


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

class cMember
{
    public: 
    int id;

    cMember();
    ~cMember();
};

cMember::cMember()
{
    cout<<"member constructor\n";
}

cMember::~cMember() 
{
    cout<<"member destructor\n";
};

class cDirectory
{
    std::vector<cMember> memberList;

public:
    cDirectory();
    ~cDirectory();

    void Populate();
};


cDirectory::cDirectory()
{
    cout<<"directory constructor\n";
}

cDirectory::~cDirectory()
{
    cout<<"directory desctructor\n";
}

void cDirectory::Populate()
{
    for(int i = 0; i < 2; i++)
    {
        cout<<"A\n";
        cMember t;
        memberList.push_back(t);
        cout<<"B\n";
    }
    cout<<"C\n";
}

int main( int argc, const char ** argv )
{
    cDirectory dir;
    dir.Populate();
    exit(0);
}

Looking at the output of this program, the second iteration calls the members destructor between A and B. I assume this call is the vector reallocating and repopulating, and destroying the members it had in it before the reallocation.

How can vector be destroying objects, but not constructing their replacements?


Solution

  • Because cMember is statically allocated, when the function goes out of scope that memory would be lost. This would be problematic for the vector if it still had a reference to that point in memory. So instead, std::vector will copy construct that object. This gives the vector its own dynamically allocated copy, which will exist for the vector even after the function goes out of scope.

    I modified your code to print this as well, and this is the output:

    directory constructor
    A
    member constructor 0x7fff572e86f8
    B
    member destructor 0x7fff572e86f8
    A
    member constructor 0x7fff572e86f8
    member destructor 0x7fc1dbc04c80
    B
    member destructor 0x7fff572e86f8
    C
    

    As you can see, the object being destroyed between A and B was not constructed by your functions. Instead, it was the copy constructed object used by the std::vector.