0
votes

Am bit confused about the output of constructor calls during erase.

#include <iostream>
#include <vector>

 using namespace std;
class sample
{
   public:
     sample(){ cout<<"Deafult cons\n";}
     sample( int a) { cout<<"Param Cons\n"; }
     sample( const sample& Obj ) { cout<<"Copy called\n";}
     sample( sample &&objj) { cout<<"Copy Reference cons \n";}
     sample& operator=(sample&& other){ cout<<"Copy equal cons \n";}
     sample& operator=(sample& other){ cout<<"Normal  equal  cons \n";}
     ~sample() {cout<<"Destroy\n";}

};

int main()
{
    vector < sample > Object;
    Object.push_back( sample() );
    Object.push_back( sample() );
    cout<<" ********* Going to call Erase ********** \n";
    Object.erase( Object.begin() );
    cout<<" ********* End of call Erase ********** \n";
    return 0; 
}

The output is Deafult cons // Understood, creation of temp object
Copy Reference cons // Understood, move assignment
Destroy // Destruction of temp object
Deafult cons // construction of second temp object
Copy Reference cons // Move assignent for second temp to vector
Copy called // Here, i understood coz of memory shortage, vector increased the size and trying to copy the old objects.
Destroy
Destroy
********* Going to call Erase **********
Copy equal cons
Destroy
********* End of call Erase **********
Destroy

My Question,

After size is increased, why system is calling COPY Contructor instead of Move assignment operator or Move constructor to copy/move the old object ?

Coz calling copy constructor again lead to performance issue.

Correct me if am wrong

1

1 Answers

1
votes

After size is increased, why system is calling COPY Contructor instead of Move assignment operator or Move constructor to copy/move the old object ?

The move constructor of sample is not used as it is not noexcept.

The copy constructor has the advantage that the original is preserved. So if an exception is thrown during copying, the copies created so far can be discarded and we can go back to the original state of the vector.

However, if an exception is thrown during a sequence of moves, we have already partly changed the state of the original values and cannot easily restore the original state. Trying to "move back" some of the already moved objects is somewhat likely to throw more exceptions, and possibly make it even worse, so is not attempted.

So, if the class has a copy constructor, it is preferred over a potentially throwing move constructor. If the class is only movable, but not copyable, the moves will be attempted and we will have to cross our fingers and hope it works. Otherwise we might lose some members during an exception.