zoukankan      html  css  js  c++  java
  • 实战c++中的vector系列--emplace_back造成的引用失效

    上篇将了对于struct或是class为何emplace_back要优越于push_back,可是另一些细节没有提及。今天就谈一谈emplace_back造成的引用失效。

    直接撸代码了:

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> 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 <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> 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 <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> 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 <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> 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 <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> 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就不失效呢?

  • 相关阅读:
    理解区块链之前,先上手体验一把数字货币(2018-04-06 陈浩 第6讲)
    约瑟夫·卢宾《以太坊:从底层揭秘区块链应用和机会》2018-04-21
    以太坊智能合约介绍,Solidity介绍
    新浪微博 [异常问题] 414 Request-URL Too Large
    Google自动广告,将广告代码放置在 HTML 中的什么位置?
    囤币一族,被中国市场遗忘的价值币ADA
    基于EOS开发的Dapp大全
    朴素贝叶斯算法,贝叶斯分类算法,贝叶斯定理原理
    区块链3.0 ada Cardano卡尔达诺如何获得一致好评?
    拜占庭将军问题(Byzantine Generals Problem),一个关于分布式系统容错问题故事
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7150456.html
Copyright © 2011-2022 走看看