标准::矢量清除函数的实现

Implementation of std::vector clear function

本文关键字:实现 函数 标准 清除      更新时间:2023-10-16

我一直在试图理解 std::vector 中的 clear() 函数是如何工作的,我试图模拟 std::vector 的工作原理。

到目前为止,我已经了解到clear()会破坏所有对象,但保留向量的容量。

我不明白的一点是如何调用向量中对象的析构函数。

class A {
  public:
    A(int a) {
        m_a = a;
        cout << "Constructed object number: " << a << endl;
    }
    ~A() {
        cout << "Destructed object number: " << m_a << endl;
    }
    int m_a;
};
int main() {
  char** memory =  new char*[100];
  A t1(1);
  memory[sizeof(A)*10] = reinterpret_cast<char *>(&t1);
  A* t = reinterpret_cast<A*>(memory[sizeof(A)*10]);
  cout << t->m_a << endl;
  //Trying to figure out on how to clear the vector. 
  memory[sizeof(A)*10] = NULL;
  //Testing on how the destructor is getting called
  vector<A*> vec;
  vec.push_back(&A(2));  // I know it is wrong, just here for understanding purposes.
  A t2(3);
  vec.push_back(&t2);
  cout << "Clear" << endl;
  vec.clear();
  cout << "End" << endl;
  return 0;
}
清除向量不是调用"t2"的析构函数,

因为它是这里的指针,但是如果我存储对象,那么"t2"的析构函数将在清除函数中被调用。

这只是为了理解 std::vector 的实际工作原理。

@Anurag关于

STL 容器的一件非常重要的事情:无论容器类型(序列容器、关联容器和无序容器)如何,它都会保留对象/指针/基元类型的副本。

现在回到你的疑问 1. 与对象和 2.用指针,下面我用例子解释:

  1. 对象类型示例(请参阅输出,您将清楚):

#include <iostream> 
#include<vector>
using namespace std;
class Achintya {
 static int counter ;
 static int i ;
  public: 
  Achintya() {
        cout<<"Achintya Constructor called : " << ++i <<endl;
    }
  ~Achintya() {
        
        cout<<"Achintya destructor called : " << ++counter <<endl;
    }
    Achintya(const Achintya&) {
         cout<<"Achintya copy constructor  called : "<<endl;
    }
};
int Achintya:: i;
int Achintya:: counter;
int main() { 
    
    vector<Achintya> VecAchintya;
    
    Achintya  a1;
    // Address of the pointer 
    cout << " 1st object address : " <<&a1 <<endl;
   
    
    //Push back to vector 
    // it is just a copy and store in vector (copy constructor is begin invoke )
    VecAchintya.push_back(a1);
   
    
    cout << " =============================================" << endl;
    cout<< " Number of element present in vector is : " << VecAchintya.size() << endl;
    cout << " =============================================" << endl;
    
  
    // cli is not iterator 
    for(auto& cli:VecAchintya ) {
                cout  << " Adress  of  1st element is : " << &cli <<endl;
    }
    
    // it clear the object it self which is being created at the time of the push_back()
    VecAchintya.clear(); 
    
    cout << " =============================================" << endl;
    cout<< " Number of element present in vector is : " << VecAchintya.size() << endl;
    cout << " =============================================" << endl;
    
    
 }
output :: 
Achintya Constructor called : 1
 1st object address : 0x7ffd70ad339f
Achintya copy constructor  called : 
 =============================================
 Number of element present in vector is : 1
 =============================================
 Adress  of  1st element is : 0x23c6c30
Achintya destructor called : 1
 =============================================
 Number of element present in vector is : 0
 =============================================
Achintya destructor called : 2

  1. 指针类型示例(请参阅输出,您将清楚):

#include <iostream> 
#include<vector>
using namespace std;
class Achintya {
 static int counter ;
 static int i ;
  public: 
  Achintya() {
        cout<<"Achintya Constructor called : " << ++i <<endl;
    }
  ~Achintya() {
        
        cout<<"Achintya destructor called : " << ++counter <<endl;
    }
    Achintya(const Achintya&) {
         cout<<"Achintya copy constructor  called : "<<endl;
    }
  };
int Achintya:: i;
int Achintya:: counter;
int main() { 
    
    vector<Achintya *> VecAchintya;
    
    Achintya*  a1 = new Achintya();
    // Address of the pointer 
    cout << " 1st object address : " << a1 <<endl;
   
    
    //Push back to vector 
    // it is just a copy the pointer value and store 
    VecAchintya.push_back(a1);
   
    
    cout << " =============================================" << endl;
    cout<< " Number of element present in vector is : " << VecAchintya.size() << endl;
    cout << " =============================================" << endl;
    
  
    // cli is not iterator 
    for(auto& cli:VecAchintya ) {
                cout  << " Adress  of  1st element is : " << cli <<endl;
    }
    
    // it clear the pointer it self which is being stored at the time push_back()
    VecAchintya.clear(); 
    
    cout << " =============================================" << endl;
    cout<< " Number of element present in vector is : " << VecAchintya.size() << endl;
    cout << " =============================================" << endl;
    
    // call destructor explicitly 
    delete a1;
    
    
 }
 Output ::
 Achintya Constructor called : 1
 1st object address : 0x2533c20
 =============================================
 Number of element present in vector is : 1
 =============================================
 Adress  of  1st element is : 0x2533c20
 =============================================
 Number of element present in vector is : 0
 =============================================
Achintya destructor called : 1

您可能会

发现学习pop_back更容易,并将调整大小和清除视为特殊的多流行呼叫。您当然可以在自己的实现中以这种方式实现它们。