tags:

views:

100

answers:

3

For the following code:

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

 struct Test
 {

    string Str; 
    Test(const string s) :Str(s)
    { 
         cout<<Str<<" Test() "<<this<<endl;
    }
    ~Test()
    { 
         cout<<Str<<" ~Test() "<<this<<endl; 
    }
 };

 struct TestWrapper
 {
    vector<Test> vObj;
    TestWrapper(const string s)
    {
       cout<<"TestWrapper() "<<this<<endl;
       vObj.push_back(s);
    }

    ~TestWrapper() 
    { 
       cout<<"~TestWrapper() "<<this<<endl;
    }
 };

int main ()
{
   TestWrapper obj("ABC");
}

This was the output that I got on my MSVC++ compiler:

TestWrapper() 0018F854
ABC Test() 0018F634
ABC ~Test() 0018F634
~TestWrapper() 0018F854
ABC ~Test() 003D8490

Why there are two calls to Test destructor although only one Test object is being created. Is there any temporary object created in between? If yes, why there is no call to its corresponding constructor?

Am I missing something?

+2  A: 

I think that

vObj.push_back(s);

involves an implicit cast of s to Test. So what's actually happening is

vObj.push_back(Test(s));

and the temporary object gets destroyed after it is copied into the vector.

The object within the vector is constructed using a copy constructor (not the (const string s) constructor) which is why you don't see any constructor call corresponding to the destructor call.

Artelius
You said "and the temporary object gets destroyed after it is copied into the vector".The last destructor call is for the temporary object. Why doesn't it get destroyed immediately?
novice_coder
No, the first destructor call is for the temporary object. The temporary object is constructed with a string argument, which is why you see the constructor being called.
Artelius
Then why are these two values of "this" similar:ABC Test() 0018F634ABC ~Test() 0018F634
novice_coder
Because they're for the *same object*! But it's the temporary object nonetheless!
Artelius
+5  A: 

Your output doesn't account for the Test's copy constructor, which std::vector is apt to use.

The Test object you see get created is the temporary passed to push_back(), not the one actually in the vector.

Shmoopty
+2  A: 

Try adding a copy constructor to your Test:

Test(const Test &obj)
{ 
    cout<<obj.Str<<" Test() "<<this<<endl;
    Str = obj.Str;
}

You'll see the copy constructor being called as well, this call happens at the time the object is being put in the vector. So we have two calls to constructors and two calls to destructor.

codaddict