создает ли очередь копию? - PullRequest
5 голосов
/ 14 июля 2020

Если я помещаю sh существующий объект в очередь:

struct Node {int x; int y;};
std::vector<Node> vec;
vec.push_back(Node(1, 3));

std::queue<Node> q;
q.push(vec[0]);

В последней строке q сохраняет адрес (указатель или ссылку, кроме сам объект) из vec[0], или копирует весь Node объект в q?

Ответы [ 3 ]

5 голосов
/ 14 июля 2020

Он действительно создает копию. Фактически, вы всегда можете узнать, где происходит копирование или перемещение, перезаписав конструкторы копирования или перемещения:

class Node 
{
public:
    Node(int x, int y) { std::cout << "Create node" << std::endl; }
    Node(const Node&) { std::cout << "Copy node" << std::endl; }
    Node(Node&&) { std::cout << "Move node" << std::endl; }
    virtual ~Node() = default;
};

Для вашей программы это печатает

Create node
Move node
Copy node

Поскольку

std::vector<Node> vec;
vec.push_back(Node(1, 3));  // Creates a temporary node and moves it into the vector.

std::queue<Node> q;
q.push(vec[0]);             // Copys the node.
5 голосов
/ 14 июля 2020

Он будет скопирован, когда вы назначите ссылку rvalue. Он будет перемещен, если вы назначите ссылку lvalue. (временный объект).

Для проверки используйте конструктор / оператор копирования и переместите перегрузку конструктора / оператора:

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

struct Node {
    int x;
    int y;

    Node(int x, int y) : x(x), y(y)
    {
        std::cout << "constructor" << std::endl;
    }

    Node(Node const & original) : x(original.x), y(original.y)
    {
        std::cout << "copy constructor" << std::endl;
    }

    Node(Node const && original) : x(original.x), y(original.y)
    {
        std::cout << "move constructor" << std::endl;
    }

    Node & operator=(Node const & original) {
        std::cout << "assignment operator" << std::endl;
        if(this != &original) {
            x = original.x;
            y = original.y;
        }
        return *this;
    }

    Node & operator=(Node const && original) {
        std::cout << "move operator" << std::endl;
        if(this != &original) {
            x = original.x;
            y = original.y;
        }
        return *this;
    }
};


int main() {

    std::vector<Node> v;

    Node n(1,3);        // constructor
    Node m(3, 4);       // constructor

    m = n;              // assignment operator
    n = Node(2, 3);     // constructor + move operator

    v.push_back({1,2});     // constructor + move constructor
    v.push_back(n);         // copy constructor

    std::queue<Node> q;
    q.push(v[0]);           // copy constructor

    return 0;
}
3 голосов
/ 14 июля 2020

Согласно do c сигнатуры функции pu sh в очереди: std::queue::push(const value_type& val) std::queue::push(value_type&& val)

Таким образом, он в основном копируется в очередь, что можно проверить с помощью:

#include <iostream>
#include <queue>

int main() {
    int iarray[3] = { 1,2,3 };
    std::queue<int> q;
    q.push(iarray[2]);
    std::cout << q.front();
    iarray[2] = 4;
    std::cout << q.front();
    return 0;
}

Для уточнения,

Вот что происходит:

линия q.push(iarray[2]); звонки void push (const value_type& val) из класса очереди.

Определение void push (const value_type& val):

void push(const value_type& _Val) {
    c.push_back(_Val);
}

Где c - защищенный экземпляр класса _Container Строка c.push_back(_Val) фактически вызывает конструктор копирования объекта _Val

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...