涉及多次调用析构函数的奇怪C ++行为

时间:2012-04-02 03:45:49

标签: c++

我在Dev Studio 2010中运行以下代码:

struct Foo
{
    Foo() {cout << "Foo()" << endl;}
    ~Foo() {cout << "~Foo()" << endl;}
    void operator ()(const int &) const {}
};

int bar[] = {0};
for_each(begin(bar), end(bar), Foo());

输出不是我的预期,无论“bar”数组的内容如何,​​调试和发布都是相同的:

Foo()
~Foo()
~Foo()
~Foo()

我已经查看了输出的程序集,我无法理解为什么编译器会生成对析构函数的额外调用。任何人都可以向我解释到底发生了什么事吗?

2 个答案:

答案 0 :(得分:4)

这是因为在程序过程中正在创建和销毁无名临时对象 通常,在使用标准库容器和算法时,标准不提供任何保证创建临时对象的保证。允许实现创建临时对象,如果他们愿意(为了良好的性能或其他)。

请注意,您应该遵循c ++ 03中的 Rule of Three 和c ++ 11中的五个规则,以避免因临时对象而导致的任何问题创建

答案 1 :(得分:1)

对于每个都是模板化函数,并且在你使用它的情况下,参数Foo将被输入为Foo,而不是Foo&amp; FOO *

这意味着将复制Foo对象。

为什么要复制两次?一旦进入功能,一旦退出。 for_each会在Foo争论中复制匿名Foo,然后它会返回它的副本,因为它的返回类型也是Foo。

详细说明Als所说的内容:正在使用复制构造函数。

要让它不复制,你可以明确地输入它作为参考(但是,正如Als所说,这将是特定于实现的,理论上如果它愿意,for_each可以制作显式副本):

for_each<Foo&>(..., ..., ...)