意外的C ++队列行为,在弹出后丢失了对象

时间:2017-11-29 00:41:50

标签: c++

queue<vector<int>>的行为与预期不符。我似乎无法访问vector之后对pop()的引用。

#include <vector>
#include <cstdio>
#include <queue>
#include <iostream>

using namespace std;

struct TreeNode {
    string val;
    TreeNode(string x) : val(x) {}
};

int main() {

    queue<int> q = {};


    q.push(1);
    q.push(2);

    int& test = q.front();
    q.pop();
    // queue<int>; front() and then pop() behaves as expected
    cout << "test1 " << test  << " expect: 1" << endl;

    TreeNode n1("node a");
    TreeNode n2("node b");
    queue<TreeNode> q2 = {};


    q2.push(n1);
    q2.push(n2);

    TreeNode& test2 = q2.front();
    q2.pop();

    // queue<TreeNode>; front() and then pop() behaves as expected    
    cout << "test2 " << test2.val  << " expect: node b" << endl;


    vector<int> v1 = {0,1,2};
    vector<int> v2 = {2,3,4};

    queue<vector<int>> q3 = {};

    q3.push(v1);
    q3.push(v2);
    vector<int>& test3 = q3.front();
    // front() alone returns what I expected
    cout << "test3 size " << test3.size() << " expect: size 3" << endl;

    vector<int>& test4 = q3.front();
    q3.pop();
    // however front() and then pop() does not behave as expected    
    cout << "test4 size " << test3.size() << " expect: size 4" << endl;
    return 0;
}

输出:

test1 1 expect: 1
test2 node a expect: node b
test3 size 3 expect: size 3
test4 size 0 expect: size 4

Process finished with exit code 0

问题:

以上示例是否有任何代码味道?在pop()之后,我是否总是希望丢失参考?我应该在pop()之后永远不要使用参考吗?

或者vector是一个特例吗?

EDIT: knowing that dangling reference is always bad practice. I made some changes to the code and now have some follow up questions.

跟进问题:

queue<int> q = {};
q.push(1);
q.push(2);
// making a copy here
// follow up question 1: is this now correct?
int test = q.front();
q.pop();


vector<int> v1 = {0,1,2};
vector<int> v2 = {2,3,4};

queue<vector<int>> q3 = {};

q3.push(v1);
q3.push(v2);

// I am trying to make a copy here but the compiler complains:
// Parameter type mismatch: expression must be rvalue
// follow up question 2: why can't I make a copy of the vector but I can make a copy of the int in the previous example?
vector<int> test3 = q3.front();
q3.pop()

1 个答案:

答案 0 :(得分:3)

您正在存储对象的引用,然后销毁该对象。一旦你pop离开队列,它就不再在队列中了。要么制作一个对象的副本,要么不要pop它,直到你完成它为止。

同样,永远不要尝试访问不再存在的对象。结果将无法预测。