简体   繁体   中英

Implementation of std::vector clear function

I have been trying to understand how the clear() function in std::vector works, I am trying to emulate the workings of a std::vector.

So far, I have learned that clear() destroys all the objects but retains the capacity of the vector.

The bit I don't understand is how does the destructor of the objects in vector are called.

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;
}

Clearing the vector is not calling the destructor of "t2", as it is a pointer here, but if I store objects, than destructor of "t2" is getting called in clear function.

This is only for understanding purposes as to how the std::vector actually works.

@Anurag one very important thing regarding STL container: it's keep the copy of the object/pointer/primitive type irrespective of the container type(sequence containers, associative containers and unordered container).

Now come back to your doubt 1. with object and 2. With pointer , below I am explaining with example :

  1. Example Of Object type (See the output, you will be clear):

 #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. Example Of pointer type (See the output, you will be clear):

 #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 

You may find it easier to study pop_back and think of resize down and clear as special multi-pop calls. You could certainly implement them that way in your own implementation.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM