我把一个shared_ptr放入映射,但是为什么在程序结束之前对象被析构?



我为我的测试对象创建了一个shared_ptr,并把它放在std::map中,但是它的析构函数在程序结束之前被调用,我不知道为什么。

下面是我的测试代码:
class Test
{
public:
Test()
{
std::cout << "in constructor" << std::endl;
}
~Test()
{
std::cout << "in ~constructor" << std::endl;
}
Test(Test&&)      = delete;
Test(const Test&) = delete;
};

std::map<std::string, std::shared_ptr<Test>> datas;
int main(int argc, char* argv[])
{
if (true)
{
auto temp = datas["key"];
if (!temp)
{
std::cout << "create new one" << std::endl;
temp = std::make_shared<Test>();
datas.insert(std::make_pair("key", temp));
}
else
{
std::cout << "already exists,pass" << std::endl;
}
std::cout << "temp use count:" << temp.use_count() << std::endl;
}
auto other = datas["key"];
std::cout << "other use count:" << other.use_count() << std::endl;
while (true)
{
usleep(100);
}
std::cout << "program end" << std::endl;
return 0;
}

当我运行程序时,它在while (true)行等待,但输出是:

create new one
in constructor
temp use count:1
in ~constructor
other use count:0

在程序结束之前,我认为对象应该仍然在内存中,因为map保存了一个引用。

另一个问题:当我从map得到other时,为什么使用计数为0?如何以正确的方式获得对象?

顺便说一句,如果我注释掉if(true){},析构函数不会被调用,但是other的使用计数仍然是0。

operator [](std::map)将插入地图中不存在的元素。如果元素已经在映射中,std::map::insert()将无法插入任何元素。因此,您的insert()调用失败。您可以通过检查返回值来验证它:

auto [iterator, wasInserted] = datas.insert(std::make_pair("key", temp));
std::cout << "insert call was " << (wasInserted ? "successful" : "unsuccessful") << 'n';

要更新或创建不存在的元素,您可以再次使用operator[]:

if (!temp)
{
std::cout << "create new one" << std::endl;
temp = std::make_shared<Test>();
datas["key"] = temp;
}

最新更新