程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實戰c++中的vector系列--emplace_back造成的引用失效

實戰c++中的vector系列--emplace_back造成的引用失效

編輯:C++入門知識

實戰c++中的vector系列--emplace_back造成的引用失效


今天就談一談emplace_back造成的引用失效。

直接撸代碼了:

#include 
#include 
#include 
using namespace std;

int main()
{
    vector ivec;
    ivec.emplace_back(1);
    ivec.emplace_back(ivec.back());
    for (auto it = ivec.begin(); it != ivec.end(); ++it)
        cout << *it << " ";
    return 0;
}

//輸出:
1 -572662307 

嘗試1:不直接給emplace_back傳遞ivec.back():

#include 
#include 
#include 
using namespace std;

int main()
{
    vector ivec;
    ivec.emplace_back(1);
    auto &it = ivec.back();
    ivec.emplace_back(it);
    for (auto it = ivec.begin(); it != ivec.end(); ++it)
        cout << *it << " ";
    return 0;
}
輸出:
1 -572662307 

嘗試2:不給emplace_back傳遞引用:

#include 
#include 
#include 
using namespace std;

int main()
{
    vector ivec;
    ivec.emplace_back(1);
    auto it = ivec.back();
    ivec.emplace_back(it);
    for (auto it = ivec.begin(); it != ivec.end(); ++it)
        cout << *it << " ";
    return 0;
}
輸出:
1 1

我們如願以償,這時候應該可以得到結論了,ivec.back()返回的是引用,但是這個引用失效了,所以才會輸出不正確;我們之前也提到過,重新分配內存會造成迭代器的失效,這裡是造成了引用的失效。

再回頭看看emplace_back的描述:
if a reallocation happens, all iterators, pointers and references related to this container are invalidated.
Otherwise, only the end iterator is invalidated, and all other iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

進一步。

嘗試3:避免emplace_back引起重新分配內存:

#include 
#include 
#include 
using namespace std;

int main()
{
    vector ivec;
    ivec.reserve(4);
    ivec.emplace_back(1);
    ivec.emplace_back(ivec.back());
    for (auto it = ivec.begin(); it != ivec.end(); ++it)
        cout << *it << " ";
    return 0;
}
輸出:
1 1

但是這個時候問題來了,如果不使用emplace_back而改用push_back呢?

#include 
#include 
#include 
using namespace std;

int main()
{
    vector ivec;
    ivec.push_back(1);
    ivec.push_back(ivec.back());
    ivec.push_back(ivec.back());
    ivec.push_back(ivec.back());
    for (auto it = ivec.begin(); it != ivec.end(); ++it)
        cout << *it << " ";
    return 0;
}
//輸出:
1 1 1 1

為什麼使用push_back就不失效呢?

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved