std::map 对象析构函数被调用?

Kay*_*yla 0 c++

我有一个全局映射对象,其中包含一个 ID 和一个类对象,但我不明白为什么调用映射中对象的析构函数。

#include <map>
#include <iostream>
#include <cassert>
#include <chrono>
#include <thread>
class TestMapObject{

private:
    std::string m_sName;
public:
    TestMapObject(const std::string& sName){
        std::cout << "Constructor called" << std::endl;
        m_sName = sName;
    }
    ~TestMapObject(){
        std::cout << "Destructor called" << std::endl;
    }
    const std::string& GetName(){
        return m_sName;
    }
};

namespace Test{

    enum ETestMapKeyId{
      k_ETestMapKeyNone = 0,
        k_ETestMapKeyFirst,
        k_ETestMapKeySecond,
    };

    std::map<ETestMapKeyId, TestMapObject> g_tMap;

    TestMapObject* GetMapObjectById(ETestMapKeyId eID){
        auto itFound = g_tMap.find(eID);
        
        assert(itFound != g_tMap.end());
        
        return &itFound->second;
    }
}



int main(){
    Test::g_tMap.insert(std::pair<Test::ETestMapKeyId,TestMapObject>(Test::k_ETestMapKeyFirst,TestMapObject("Alice")));
    Test::g_tMap.insert(std::pair<Test::ETestMapKeyId,TestMapObject>(Test::k_ETestMapKeySecond,TestMapObject("Mocha")));
    //destructor gets called here
    std::cout << " are we destructed? " << std::endl;
    
    TestMapObject* tmKeyFirst = Test::GetMapObjectById(Test::k_ETestMapKeyFirst);
    TestMapObject* tmKeySecond = Test::GetMapObjectById(Test::k_ETestMapKeySecond);
    
    
    
    for(;;){
        std::this_thread::sleep_for (std::chrono::seconds(1));
        std::cout << tmKeyFirst->GetName() << std::endl ;
        std::cout << tmKeySecond->GetName() << std::endl ;
    }
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

我能够使用 GetMapObjectById 检索指向对象的指针,并连续打印它们的名称(考虑到调用了它们的析构函数,这可能是未定义的行为)。但我不确定为什么在应用程序结束之前调用析构函数。

输出

Constructor called
Destructor called
Destructor called
Constructor called
Destructor called
Destructor called
 are we destructed? 

---continues loop print
Alice
Mocha
Run Code Online (Sandbox Code Playgroud)

for*_*818 5

您看到的不是std::map被破坏,而是您用来在地图中插入元素的临时对象。您可以使用 emplace 来避免构建(和破坏)该临时对象:

Test::g_tMap.emplace(Test::k_ETestMapKeyFirst,"Alice");
Test::g_tMap.emplace(Test::k_ETestMapKeySecond,"Mocha");
Run Code Online (Sandbox Code Playgroud)

现场演示