【问题标题】:C++ Reference variable scope issueC ++参考变量范围问题
【发布时间】:2012-09-14 10:38:42
【问题描述】:

我试图弄清楚为什么我的 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::shared_ptr&lt;Tag&gt; tag(new Tag());?
  • 我想避免动态创建它,因为当我对为什么正确的值最终出现在地图中但析构函数在循环结束
  • 你确定被破坏的Tag对象是tag,而不是std::pair&lt;string, Tag&gt;(tagName, tag)中的副本吗?
  • 是的,这就是问题所在,我没有意识到正在创建临时文件

标签: c++ scope destructor


【解决方案1】:

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

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 是在调用者提供的内存区域中构造的,因此函数结果不进行复制。

【讨论】:

  • 谢谢!我不知道 pair 会创建一个临时变量,这解释了它:) map 指针是一个 union 结构的成员,它还可以包含一个指向数据块的 char* 指针,所以它主要是为了保持一致性
  • 我仍然有同样的问题,我最终通过使用 Compound->insert(std::pair(tagName, tag));
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2011-03-16
    • 2016-08-30
    • 2011-11-21
    • 2011-04-13
    相关资源
    最近更新 更多