简体   繁体   English

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

[英]std::map object destructor getting called?

I have a global map object which contains an ID and a class object, but I don't understand why the destructor for the objects in the map are getting called.我有一个包含 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;
}

I'm able to retrieve a pointer to the objects with GetMapObjectById and continuously able to print their name (Which might be undefined behavior considering their destructor was called).我能够使用 GetMapObjectById 检索指向对象的指针,并且能够连续打印它们的名称(考虑到调用了它们的析构函数,这可能是未定义的行为)。 But I'm unsure why the destructor gets called before the application ends..但我不确定为什么在应用程序结束之前调用析构函数..

Output输出

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

---continues loop print
Alice
Mocha

What you see is not the std::map getting destroyed, but the temporaries you are using to insert elements in the map.您看到的不是std::map被破坏,而是您用来在地图中插入元素的临时对象。 You can use emplace to avoid the construction (and destruction) of that temporaries:您可以使用 emplace 来避免构建(和破坏)该临时对象:

Test::g_tMap.emplace(Test::k_ETestMapKeyFirst,"Alice");
Test::g_tMap.emplace(Test::k_ETestMapKeySecond,"Mocha");

Live Demo现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM