【发布时间】:2026-02-13 04:50:02
【问题描述】:
为什么在下面的代码中会出现一对“额外的”复制构造函数和析构函数?
当叮咚的构造函数将 STL 容器作为参数时会发生这种情况(我尝试过 std::vector 和 std::list)。它可能发生在其他事情上吗?如果构造函数取而代之的是指针,则不会发生。如果我在堆上分配 ding 也不会发生( Dingledong* ding = new Dingledong(v) )。
#include <list>
#include <iostream>
class Dingledong{
public:
Dingledong(std::list<int> numbers)
{
std::cout << "construction\n";
numbers_ = numbers;
}
Dingledong(Dingledong const& other)
{
std::cout << "COPY construction\n";
}
~Dingledong()
{
std::cout << "destructed\n";
// I would do some cleanup here.. unsubscribe from events, whatever..
// but the destructor is called sooner than I would expect and thus
// the cleanup is done prematurely.
}
std::list<int> numbers_;
};
void diller()
{
std::cout << "diller started.. " << std::endl;
std::list<int> v = std::list<int>(34);
// Having an STL container as parameter in constructor causes Dingledong's copy constructor to
// be used to create a temporary Dingledong which is immediately destructed again. Why?
Dingledong ding = Dingledong(v);
std::cout << "Has ding been destructed?\n";
}
int main()
{
diller();
system("pause");
}
输出:
diller started...
construction
COPY construction // I didn't expect this to happen
destructed // I didn't expect this to happen
Has ding been destructed?
destructed
提前谢谢你!
【问题讨论】:
-
你用的是什么编译器?我本来希望该副本被省略。另外,是什么让您认为它与“STL”容器有关?
-
我的编译器是 Visual Studio 2013 附带的。STL 容器只是我迄今为止发现的唯一模式。我希望它会发生在其他事情上。
-
您是否在关闭优化的情况下进行编译?如果副本没有在 Release 模式下被删除,我会感到非常惊讶。
-
好吧,在做出此类声明并添加各种可能不相关的信息和标签之前,您应该检查一下。
-
@LokiAstari 我可以确认 VS2013 中的发布版本仍然具有相同的行为。
标签: c++ destructor copy-constructor copy-elision