当我运行以下程序时,析构函数被调用两次,我试图理解为什么?
#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() );
}
输出如下
Constructor
0 ,
1 ,
2 ,
3 ,
4 ,
Destructor
Destructor
答案 0 :(得分:5)
三次违规的经典规则。试试这个:
#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() );
}
输出是:
构造
0,
1,
2,
3,
4,
构造函数(副本)
析构函数
析
答案 1 :(得分:3)
原因是std::for_each
通过值获取其参数,这会导致您提供的参数的副本。
因此,通过执行sample()
对您创建的临时文件的破坏将负责这两条销毁消息中的一条(最后一条,因为临时在评估创建它的完整表达式后被破坏)
另一方面,第一个销毁消息来自std::for_each
正在处理的副本的销毁。
答案 2 :(得分:2)
std::for_each
将按值获取函数对象,从而导致它被复制。因此,为sample()
创建的临时对象调用一个析构函数,并为副本调用另一个析构函数。
答案 3 :(得分:1)
如果您编写了一个复制构造函数,您会看到该仿函数被复制到算法中。然后两个副本都被破坏。有可能返回仿函数,并且会有3份副本,因此其中一份副本正在被删除。