简体   繁体   English

c++中使用向量时如何调用构造函数和析构函数

[英]How does the constructors and destructors are called when using vectors in c++

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. *我得到以下 output。 Not very clear how the constructors and destructors are called and in which order.不太清楚如何调用构造函数和析构函数以及调用顺序。 could some one please throw some light?有人可以请一些光吗? * *

Output: Output:
construct 2 employee id 1构造 2 员工 ID 1
construct 2 employee id 2构造 2 员工 ID 2
construct 2 employee id 3构造 2 员工 ID 3
construct 2 employee id 4构造 2 员工 id 4
construct 2 employee id 5构造 2 员工 id 5
construct 1 employee id 10构造 1 个员工 id 10
construct 1 employee id 10构造 1 个员工 id 10
construct 1 employee id 10构造 1 个员工 id 10
copy construct 3 employee id 1复制构造 3 员工 ID 1
copy construct 3 employee id 2复制构造 3 员工 ID 2
copy construct 3 employee id 1复制构造 3 员工 ID 1
destructor析构函数
copy construct 3 employee id 3复制构造 3 员工 ID 3
copy construct 3 employee id 1复制构造 3 员工 ID 1
copy construct 3 employee id 2复制构造 3 员工 ID 2
destructor析构函数
destructor析构函数
copy construct 3 employee id 4复制构造 3 员工 ID 4
copy construct 3 employee id 5复制构造 3 员工 ID 5
copy construct 3 employee id 1复制构造 3 员工 ID 1
copy construct 3 employee id 2复制构造 3 员工 ID 2
copy construct 3 employee id 3复制构造 3 员工 ID 3
copy construct 3 employee id 4复制构造 3 员工 ID 4
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
copy construct 3 employee id 10复制构造 3 员工 ID 10
copy construct 3 employee id 10复制构造 3 员工 ID 10
copy construct 3 employee id 10复制构造 3 员工 ID 10
construct 2 employee id 20构造 2 个员工 id 20
move construct 4 employee id 20移动构造 4 员工 ID 20
copy construct 3 employee id 1复制构造 3 员工 ID 1
copy construct 3 employee id 2复制构造 3 员工 ID 2
copy construct 3 employee id 3复制构造 3 员工 ID 3
copy construct 3 employee id 4复制构造 3 员工 ID 4
copy construct 3 employee id 5复制构造 3 员工 ID 5
copy construct 3 employee id 10复制构造 3 员工 ID 10
copy construct 3 employee id 10复制构造 3 员工 ID 10
copy construct 3 employee id 10复制构造 3 员工 ID 10
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
destructor析构函数
construct 2 employee id 30构造 2 个员工 id 30
move construct 4 employee id 30移动构造 4 员工 ID 30
destructor析构函数
construct 2 employee id 40构造 2 个员工 id 40
move construct 4 employee id 40移动构造 4 员工 ID 40
destructor析构函数
construct 2 employee id 50构造 2 个员工 id 50
move construct 4 employee id 50移动构造 4 员工 ID 50
destructor析构函数
construct 2 employee id 60构造 2 个员工 id 60
move construct 4 employee id 60移动构造 4 员工 ID 60
destructor析构函数
1 1
2 2
3 3
4 4
5 5
10 10
10 10
10 10
20 20
30 30
40 40
50 50
60 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.对您的代码稍作修改将使 output 易于理解。 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.并更改您的 main 以提供更小但相似的 output。 I added a few cout s to separate things and make it more understandable when viewing the output:在查看 output 时,我添加了一些cout来分隔事物并使其更易于理解:

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:我拿到的output在下面,我将其拆分并解释:

Some definitions regarding vector:关于向量的一些定义:

  • Capacity : the number of elements that can be held in currently allocated storage容量:当前分配的存储中可以容纳的元素数量
  • Size : the number of elements in vector Size : 向量中的元素个数

Code: employee s[3]={1,2};代码: employee s[3]={1,2};

Output: 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.调用了三个构造函数,2 个employee(int)和 1 个 default。 The first two elements of array call the employee(int) .数组的前两个元素称为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: 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: 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

Lesson: Use reserve() whenever you can.教训:尽可能使用reserve()

Moreover, look into vector::clear() , vector::shrink_to_fit , see what it does.此外,查看vector::clear()vector::shrink_to_fit ,看看它做了什么。 Read the docs for additional info.阅读文档以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在构造函数和析构函数被调用时被调用? 他们实际上在做什么? C ++ - Why are constructors and destructors called when they are? What are they actually doing? C++ 使用函数对象的C++线程,如何调用多个析构函数而不是构造函数? - C++ thread using function object, how are multiple destructors are called but not the constructors? C ++类组合 - 何时执行构造函数和析构函数 - C++ Class Composition - When does constructors and destructors get executed C++ - 阐明何时以及如何调用析构函数 - C++ - Clarifying when and how destructors are called 构造函数和析构函数 - c ++ - constructors and destructors - c++ C ++基本构造函数/向量问题(1个构造函数,2个析构函数) - C++ basic constructors/vectors problem (1 constructor, 2 destructors) 如何在C ++中实现构造函数和析构函数? - How are constructors and destructors implemented in C++? C ++! 如何调用析构函数 - C++! How are destructors called 何时在运算符重载示例C ++中调用构造函数和析构函数 - When Do Constructors and Destructors Get Called in Operator Overload Example C++ C++中析构函数和构造函数的调用顺序是什么 - What is the order in which the destructors and the constructors are called in C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM