Why the destructors are called twice for this functor?

a 夏天 提交于 2019-12-22 11:23:39

问题


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

回答1:


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




回答2:


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.




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/15999691/why-the-destructors-are-called-twice-for-this-functor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!