As noted above newcustomer.clear() will empty the vector, but it won't take care of the pointers. HadeS takers care of that problem in his or her solution. Here are a few more ways to solve the problem.
Unlike some languages, in C++ one does not have to make a pointer with new
. This approach discards the pointer and directly stores the Customer in the vector. This is generally the safest solution as you have to work at it to make this solution go wrong.
int main()
{
vector<Customer> newcustomer;
newcustomer.push_back(Customer("III", 123333, 555));
newcustomer.push_back(Customer("LOL", 122222, 444));
newcustomer.push_back(Customer("PPL", 121111, 333));
// do stuff
newcustomer.clear();
return 0;
}
This is a bit clunky. You make a temporary Customer (calls constructor) and copy it into the vector (calls copy constructor). With the appropriate debugging statements int he Customer constructors and destructor you wind up with crap that looks like this:
create III
copy III
destroy III
create LOL
copy LOL
copy III
destroy III
destroy LOL
create PPL
copy PPL
copy III
copy LOL
destroy III
destroy LOL
destroy PPL
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
3 creates, 6 copies, 9 destroys.
If Customer is composed of pointers or complex custom data types, odds are pretty good you'll need to define the copy constructor to make this work. See the Rule Of Three.
C++11 has a less cumbersome approach:
int main()
{
vector<Customer> newcustomer;
newcustomer.emplace_back("III", 123333, 555);
newcustomer.emplace_back("LOL", 122222, 444);
newcustomer.emplace_back("PPL", 121111, 333);
// do stuff
newcustomer.clear();
return 0;
}
Gets rid of a bit of the work done by the first version. Output looks like this:
create III
create LOL
copy III
destroy III
create PPL
copy III
copy LOL
destroy III
destroy LOL
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
3 creates, 3 copies, 6 destroys.
If Customer has a move constructor, the output looks like this:
create III
create LOL
move III
destroy
create PPL
move III
move LOL
destroy
destroy
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
3 creates, 3 moves, 6 destroys.
Worth the time implementing a move constructor if Customer takes a long time to copy or uses a lot of RAM you'd rather not duplicate even temporarily. Though if you're using a lot of RAM, generally the copy is going to take a long time.
Important note: See how there are a bunch of destroy
s that don't say who they were? That's because the move constructor literally moves the data from source to destination. Source no longer has any data. It's up to the move constructor to not leave the source in such a state that source will exhibit undefined behaviour if used after the move. And Welcome to the Rule of 5.
If for some reason you have to have pointers, wrapping the suckers in smart pointers can make your life a lot easier on the memory management front. For example:
int main()
{
vector<unique_ptr<Customer>> newcustomer;
newcustomer.emplace_back(new Customer("III", 123333, 555));
newcustomer.emplace_back(new Customer("LOL", 122222, 444));
newcustomer.emplace_back(new Customer("PPL", 121111, 333));
// do stuff
newcustomer.clear();
return 0;
}
This one's output looks like the bee's knees:
create III
create LOL
create PPL
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
But what isn't being displayed is the unique_ptrs are being created, moved, and destroyed at the same rate as Customers in the previous sample. Depending on the cost of the Customer's move constructor, you may or may not save any time or effort with the unique_ptr.