C++ 引用变量范围问题

C++ Reference variable scope issue

本文关键字:问题 范围 变量 引用 C++      更新时间:2023-10-16

我试图弄清楚为什么我的 Tag 类的析构函数被调用

map<string, Tag>* TestLoader::loadCompoundTag()
{
    map<string, Tag>* compound = new map<string, Tag>();
    //Create locally scoped variable
    Tag tag;
    string tagName;
    do 
    {
        loadTag(tag, tagName);
            //Copies variable into map
        compound->insert(std::pair<string, Tag>(tagName, tag));
    //Tag destructor is called before debugger breaks on this line
    } while (tag.type != TAG_End);
    return compound;
}
void TestLoader::loadTag( Tag& tag, string& name )
{
    tag.i = 0;
    name = string("Test");
}

谁能给我任何想法,为什么在那里调用析构函数?没有变量在循环的作用域中定义,一个是在循环外部创建的,另一个是在函数内创建的。谢谢!

为了插入到地图中,您正在创建一个临时的,

std::pair<string, Tag>(tagName, tag)

在完整表达式结束时,它被销毁了。

你不应该担心这一点。如有必要,可以使用emplace来避免,但是,不要担心。相反,担心函数的结果类型:

为什么需要动态分配的地图

我很确定你没有,也就是说,这是邪恶的过早优化。

因此,我强烈建议,专注于正确性,让编译器完成优化工作,然后编写......

map<string, Tag> TestLoader::loadCompoundTag() const
{
    map<string, Tag> result;
    do 
    {
        Tag tag;
        string tagName;
        loadTag(tag, tagName);
        result->emplace( std::pair<string, Tag>( tagName, tag) );
    } while (tag.type != Tag::end);
    return result;
}

很可能你甚至不需要要求编译器进行优化,以便在这里获得返回值优化,这意味着,明显的本地result是在调用方提供的内存区域中构造的,因此不会对函数结果进行复制。

> 当loadCompoundTag()返回时,Tag tag会超出范围,当发生这种情况时,将调用它的析构函数。