tags:

views:

119

answers:

3

Hello ,

Iam using borland 2006 c++

class A
{
private:
    TObjectList* list;
    int myid;
public:
 __fastcall A(int);
 __fastcall ~A();
};

__fastcall A::A(int num)
{
    myid = num;
   list = new TObjectList();
}

__fastcall A::~A()
{
}

int main(int argc, char* argv[])
{
  myfunc();
  return 0;
}

void myfunc()
{
    vector<A> vec;
    vec.push_back(A(1));
}

when i add a new object A to the vector, it calls its destructor twice, and then once when vec goes out of scope , so in total 3 times.

I was thinking it should call once when object is added, and then once when vec goes out scope.

A: 

When you hit your breakpoint, click the call stack tab at the bottom of your debugger. That way, you can find the context of each call.

rlbond
Or add a print statement.
Martin York
+6  A: 

The expression A(1) is an r-value and constructs a new A value, the compiler may then copy this into a temporary object in order to bind to the const reference that push_back takes. This temporary that the reference is bound to is then copied into the storage managed by vector.

The compiler is allowed to elide temporary objects in many situations but it isn't required to do so.

Charles Bailey
Why would it make a copy to bind an rvalue to a const reference?
Zifre
The other possibility is that the vector reallocates for some reason (e.g. it needs to be grown), and it makes a copy for this.
Zifre
I've no idea why, but it's allowed by the language and many compilers do. I imagine it makes for a simpler implementation in some way. It would be a poor implementation that, in response to a single push_back, copied the parameter, then decided to reallocate, then copy it again. In push_back you know exactly how many elements your vector will need by the end of the call so you should be able to allocate appropriate storage, then copy the new element once into its new home.
Charles Bailey
May be worth to state that C++1x requires it not to copy. C++1x also allows not to have a copy constructor, while with the current language, you will have to have a copy constructor present.
Johannes Schaub - litb
@litb: all true, my answer is purely about the current state of affairs.
Charles Bailey
+1  A: 

Try this:

#include <iostream>
#include <vector>

class A
{
    private:
        public:
            A(int num)
            {
                std::cout << "Constructor(" << num << ")\n";
            }
            A(A const& copy)
            {
                std::cout << "Copy()\n";
            }
            A& operator=(A const& copy)
            {
                std::cout << "Assignment\n";
                return *this;
            }
            A::~A()
            {
                std::cout << "Destroyed\n";
            }
};

int main(int argc, char* argv[])
{
    std::vector<A> vec;
    vec.push_back(A(1));
}

The output on my machine is:

> ./a.exe
Constructor(1)
Copy()
Destroyed
Destroyed
>
Martin York
+1, I forgot to push the 'Post your answer' button yesterday... but I had this same test written with the same results (darwin g++ 4.0). This is fairly simple and rather standard code, so I would be really surprised if any compiler behaved differently.
David Rodríguez - dribeas