我创建了一个简单的测试用例,展示了我在处理的较大代码库中注意到的奇怪行为。这个测试用例如下。我依靠 STL Map 的“[]”运算符在此类结构的映射中创建一个指向结构的指针。在下面的测试用例中,行...
TestStruct *thisTestStruct = &testStructMap["test"];
...获取指针(并在 map 中创建一个新条目)。我注意到的奇怪之处在于,这一行不仅导致在映射中创建一个新条目(因为“[]”运算符),而且由于某种原因它导致结构的析构函数被额外调用两次。我显然遗漏了一些东西 - 非常感谢任何帮助! 谢谢!
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct TestStruct;
int main (int argc, char * const argv[]) {
map<string, TestStruct> testStructMap;
std::cout << "Marker One\n";
//why does this line cause "~TestStruct()" to be invoked twice?
TestStruct *thisTestStruct = &testStructMap["test"];
std::cout << "Marker Two\n";
return 0;
}
struct TestStruct{
TestStruct(){
std::cout << "TestStruct Constructor!\n";
}
~TestStruct(){
std::cout << "TestStruct Destructor!\n";
}
};
上面的代码输出如下...
/*
Marker One
TestStruct Constructor! //makes sense
TestStruct Destructor! //<---why?
TestStruct Destructor! //<---god why?
Marker Two
TestStruct Destructor! //makes sense
*/
...但我不明白是什么导致了 TestStruct 的析构函数的前两次调用? (我认为最后的析构函数调用是有意义的,因为 testStructMap 超出了范围。)
最佳答案
std::map<>::operator[]
的功能相当于
(*((std::map<>::insert(std::make_pair(x, T()))).first)).second
表达式,如语言规范中所指定。如您所见,这涉及默认构造类型为 T
的临时对象。 , 将其复制到 std::pair
对象,稍后将(再次)复制到 map 的新元素中(假设它不存在)。很明显,这会产生一些中间T
对象。这些中间物体的破坏是您在实验中观察到的。你错过了他们的 build ,因为你没有从你类(class)的复制构造者那里产生任何反馈。
中间对象的确切数量可能取决于编译器优化功能,因此结果可能会有所不同。
关于c++ - 在结构的 STL 映射中,为什么 "[ ]"运算符会导致结构的 dtor 被额外调用 2 次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4017892/