Reputation: 1595
When I run the following program, the destructor is called twice and I'm trying to understand why?
#include <iostream>
#include <vector>
#include <algorithm>
class sample
{
public:
sample() { std::cout << "Constructor " << std::endl; }
~sample() { std::cout << "Destructor" << std::endl; }
void operator()(int i)
{
std::cout << i << " , " << std::endl;
}
};
int main()
{
std::vector<int> iNumbers;
for ( int i = 0 ; i < 5 ; ++i)
iNumbers.push_back(i);
std::for_each(iNumbers.begin() , iNumbers.end() , sample() );
}
The output is as folllows
Constructor
0 ,
1 ,
2 ,
3 ,
4 ,
Destructor
Destructor
Upvotes: 2
Views: 646
Reputation: 182819
Classic rule of three violation. Try this:
#include <iostream>
#include <vector>
#include <algorithm>
class sample
{
public:
sample() { std::cout << "Constructor " << std::endl; }
sample(const sample&) { std::cout << "Constructor (copy)" << std::endl; }
~sample() { std::cout << "Destructor" << std::endl; }
sample& operator=(const sample&) { return *this; }
void operator()(int i)
{
std::cout << i << " , " << std::endl;
}
};
int main()
{
std::vector<int> iNumbers;
for ( int i = 0 ; i < 5 ; ++i)
iNumbers.push_back(i);
std::for_each(iNumbers.begin() , iNumbers.end() , sample() );
}
Output is:
Constructor
0 ,
1 ,
2 ,
3 ,
4 ,
Constructor (copy)
Destructor
Destructor
Upvotes: 5
Reputation: 4207
If you wrote a copy constructor, you would see that the functor is copied into the algorithm. Both copies are then destructed. There is a potential for the functor to be returned and there would be 3 copies, so one of the copies is being elided.
Upvotes: 1
Reputation: 110698
std::for_each
will take the function object by value, causing it to be copied. So one destructor is called for the temporary object created by sample()
and the other for the copy.
Upvotes: 2
Reputation: 126502
The reason is that std::for_each
takes its argument by value, and this results in a copy of the argument you provide being made.
Therefore, the destruction of the temporary you create by doing sample()
will be responsible for one of those two destruction messages (the last one, since the temporary is destructed after the evaluation of the full expression that creates it).
The first destruction message, on the other hand, comes from the destruction of the copy that std::for_each
is working on.
Upvotes: 3