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 :
#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
#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.