2

当我运行以下程序时,析构函数被调用了两次,我试图理解为什么?

#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
4

4 回答 4

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 ,
构造函数(副本)

构函数 析构函数

于 2013-04-14T13:41:10.897 回答
3

原因是它通过 valuestd::for_each获取其参数,这会导致您提供的参数的副本被制作。

因此,您通过做创建的临时对象的销毁sample()将负责这两个销毁消息之一(最后一个,因为临时对象在评估创建它的完整表达式后被销毁)。

另一方面,第一个销毁消息来自std::for_each正在处理的副本的销毁。

于 2013-04-14T13:39:43.927 回答
2

std::for_each将按值获取函数对象,导致它被复制。因此,为创建的临时对象调用一个析构函数,sample()为副本调用另一个析构函数。

于 2013-04-14T13:39:51.050 回答
1

如果您编写了一个复制构造函数,您会看到仿函数被复制到算法中。然后两个副本都被销毁。函子有可能被返回,并且会有 3 个副本,因此其中一个副本被省略。

于 2013-04-14T13:40:17.797 回答