2012-09-22 24 views
1

我試圖找出爲什麼我的Tag類的析構函數被調用C++參考變量的作用域問題

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"); 
} 

誰能給我任何的想法,爲什麼析構函數被調用呢?在循環的範圍中沒有定義任何變量,一個是在循環外創建的,另一個是在函數內部創建的。謝謝!

+0

爲什麼不'std :: shared_ptr 標籤(新標籤());'? – jweyrich

+0

我想避免動態創建它,因爲它只是要被複制到地圖中,當我有點困惑時,爲什麼正確的值在地圖中結束,但在循環結束之前調用析構函數 – Istinra

+2

您確定被破壞的'Tag'對象是'tag',而不是'std :: pair (tagName,tag)'中的副本。 – updogliu

回答

2

爲了插入到你正在創建一個臨時的地圖,

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

在充分表達它摧毀的終結。

你不應該擔心這一點。如有必要,可以使用emplace來避免,但不要擔心。相反,擔心你的功能的結果類型:

爲什麼你需要一個動態分配的地圖

我敢肯定,你不這樣做,即那是邪惡的過早優化。

因此,我強烈建議,注重正確性,讓編譯器完成其優化工作,並寫入&hellip;

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在調用者提供的存儲區域構造,因此不會爲功能結果進行復制。

+0

謝謝!我不知道對會創建一個臨時變量,這解釋了它:)映射指針是一個聯合結構的成員,它也可以包含一個char *指向一個數據塊的指針,所以它主要是爲了一致性 – Istinra

+0

我還有與emplace相同的問題,我最終通過使用compound-> insert(std :: pair (tagName,tag))來解決它。 – Istinra

2

Tag tagloadCompoundTag()返回時超出範圍,當發生這種情況時,將調用它的析構函數。