I was trying out a simple code below
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class employee
{
private:
int emp_id;
public:
void getEmpid(){cout<<emp_id<<endl;}
void setEmpid(){ cin>>emp_id;}
employee():emp_id(10){cout<<"construct 1 "<<"employee id "<<emp_id<< endl;}
employee(int empid):emp_id(empid){cout<<"construct 2 "<<"employee id "<<emp_id<<endl;}
employee(const employee &emp):emp_id(emp.emp_id){cout<<"copy construct 3 "<<"employee id "<<emp_id<<endl;}
employee(employee&& other) : emp_id(other.emp_id) {cout<<"move construct 4 "<<"employee id "<<emp_id<<endl;}
~employee(){cout<<"destructor"<<endl;}
};
int main()
{
vector<employee>a;
employee s[8]={1,2,3,4,5};
for(int i=0;i<sizeof(s)/sizeof(s[0]);i++)
a.push_back(s[i]);
a.push_back(20);
a.push_back(30);
a.push_back(40);
a.push_back(50);
a.push_back(60);
for(int i=0;i<a.size();i++)
a[i].getEmpid();
return 0;
}
*I get the below output. Not very clear how the constructors and destructors are called and in which order. could some one please throw some light? *
Output:
construct 2 employee id 1
construct 2 employee id 2
construct 2 employee id 3
construct 2 employee id 4
construct 2 employee id 5
construct 1 employee id 10
construct 1 employee id 10
construct 1 employee id 10
copy construct 3 employee id 1
copy construct 3 employee id 2
copy construct 3 employee id 1
destructor
copy construct 3 employee id 3
copy construct 3 employee id 1
copy construct 3 employee id 2
destructor
destructor
copy construct 3 employee id 4
copy construct 3 employee id 5
copy construct 3 employee id 1
copy construct 3 employee id 2
copy construct 3 employee id 3
copy construct 3 employee id 4
destructor
destructor
destructor
destructor
copy construct 3 employee id 10
copy construct 3 employee id 10
copy construct 3 employee id 10
construct 2 employee id 20
move construct 4 employee id 20
copy construct 3 employee id 1
copy construct 3 employee id 2
copy construct 3 employee id 3
copy construct 3 employee id 4
copy construct 3 employee id 5
copy construct 3 employee id 10
copy construct 3 employee id 10
copy construct 3 employee id 10
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
construct 2 employee id 30
move construct 4 employee id 30
destructor
construct 2 employee id 40
move construct 4 employee id 40
destructor
construct 2 employee id 50
move construct 4 employee id 50
destructor
construct 2 employee id 60
move construct 4 employee id 60
destructor
1
2
3
4
5
10
10
10
20
30
40
50
60
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
destructor
Making a little modification to your code will make the output easily understandable. Specifically, change the destructor:
~employee(){cout<<"destructor " << emp_id <<endl;} // shows emp_id when destructing
And change your main to give a smaller, yet similar output. I added a few cout
s to separate things and make it more understandable when viewing the output:
int main()
{
vector<employee>a;
std::cout << "\ncreating array of employee[3]...\n" << std::endl;
employee s[3]={1,2};
std::cout << "\nstarting loop, copy into vec a\n" << std::endl;
for(int i=0;i<sizeof(s)/sizeof(s[0]);i++) {
cout << "Vec size now: " << a.size() << " Capacity: " << a.capacity() << endl;
a.push_back(s[i]);
}
cout << "Outside, Vec size now: " << a.size() << " Capacity: " << a.capacity() << endl;
std::cout << "\ndoing push back outside loop\n" << std::endl;
a.push_back(20);
a.push_back(30);
std::cout << "\nAll done exiting...\n" << std::endl;
//removed this, since we are only talking about ctors / dtors
//reduces noise
// for(int i=0;i<a.size();i++)
// a[i].getEmpid();
return 0;
}
The output that I got was following, I will split it and explain:
Some definitions regarding vector:
Code: employee s[3]={1,2};
Output:
creating array of employee[3]...
construct 2 employee id 1
construct 2 employee id 2
construct 1 employee id 10
Three constructors are called, 2 employee(int)
and 1 default. The first two elements of array call the employee(int)
. The 3rd element is default constructed.
Code:
for(int i=0;i<sizeof(s)/sizeof(s[0]);i++) {
cout << "Vec size now: " << a.size() << " Capacity: " << a.capacity() << endl;
a.push_back(s[i]);
}
Output:
starting loop, copy into vec a
//iteration 1
Vec size now: 0 Capacity: 0 //vec is zero initially
copy construct 3 employee id 1 //id 1 is copy constructed and pushed back
//iteration 2
Vec size now: 1 Capacity: 1 //vec is now size: 1, with 1 element
//we are doing a push back, but the size needs to grow. Vector reallocates and size becomes 2. The previous memory and the elements in that memory are deallocated/destructed.
copy construct 3 employee id 2 //push back(), copy contruct into vector
copy construct 3 employee id 1 // since we reallocated, the previous memory is gone,
//we need to add the previous element as well
destructor 1 //previous element, id: 1, now being destructed.
//iteration 3
//follows the same logic as in iteration 2. size by the end will be 3 (3 elements). Capacity will be 4. That means we can do one more push back without destroying everything and reallocating.
Vec size now: 2 Capacity: 2
copy construct 3 employee id 10
copy construct 3 employee id 1
copy construct 3 employee id 2
destructor 1
destructor 2
Outside, Vec size now: 3 Capacity: 4
Code:
a.push_back(20);
a.push_back(30);
Output:
doing push back outside loop
//remember we have capacity 4
construct 2 employee id 20 //construct id 20
move construct 4 employee id 20 //move into push_back() (because 20 is temporary, rvalue)
destructor 20 //destroy what we constructed
//capacity: 4, size: 4
construct 2 employee id 30 // construct id 30
move construct 4 employee id 30 //move into push_back()
//uh oh.. capacity was full, deallocations, destructions, reconstructions:
copy construct 3 employee id 1
copy construct 3 employee id 2
copy construct 3 employee id 10
copy construct 3 employee id 20
destructor 1
destructor 2
destructor 10
destructor 20
destructor 30 //destroy our temporary id: 30
All done, now just the destructors for all the elements will be called one by one.
All done exiting...
destructor 10
destructor 2
destructor 1
destructor 1
destructor 2
destructor 10
destructor 20
destructor 30
reserve()
whenever you can. Moreover, look into vector::clear()
, vector::shrink_to_fit
, see what it does. Read the docs for additional info.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.