Перемещение объекта списков в C ++ к другому объекту - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь понять, как работает этот фрагмент кода.

// Example program
#include <iostream>
#include <string>
#include <list>

struct complex
{
  int n;
  std::string str;
  complex(int n): n(n), str("String form " + std::to_string(n)) {}
};

struct Node
{
    Node(){std::cout<<"creating obj\n";}
    Node(const Node &a){ll = a.ll; pll = a.pll;}
    Node(Node &&a){ll = std::move(a.ll); pll = std::move(a.pll);}
    Node& operator=(const Node &a){ll = a.ll; pll = a.pll; return *this;}
    Node& operator=(Node &&a){ll = std::move(a.ll); pll = std::move(a.pll); return *this;}

    ~Node()
    {
      std::cout<<"Destroying object\n";
      for(auto iter : ll)
      {
        iter = 0;
      }
      for(auto iter : pll)
      {
        delete(iter);
        iter = nullptr;
      }
    }

    std::list<int> ll;
    std::list<complex*> pll;
};

Node CreateNode()
{
    Node n;
    n.ll.push_back(1);
    n.ll.push_back(2);
    n.ll.push_back(3);
    n.ll.push_back(4);
    n.ll.push_back(5);
    n.ll.push_back(6);
    n.ll.push_back(7);

    n.pll.push_back(new complex(11));
    n.pll.push_back(new complex(21));
    n.pll.push_back(new complex(31));
    n.pll.push_back(new complex(41));
    n.pll.push_back(new complex(51));
    n.pll.push_back(new complex(61));
    n.pll.push_back(new complex(71));

    return std::move(n);
}

int main()
{
  Node m;

  std::cout<<"Before assigning Nodes\n";
  for(auto iter : m.ll)
  {
      std::cout<<iter<<" ";
  }
  std::cout<<"\n";
  for(auto iter : m.pll)
  {
      std::cout<<iter->n<<", "<<iter->str<<" --> ";
  }
  std::cout<<"\n";

  m = CreateNode();

  std::cout<<"After assigning Nodes\n";
  for(auto iter : m.ll)
  {
      std::cout<<iter<<" ";
  }
  std::cout<<"\n";
  for(auto iter : m.pll)
  {
      std::cout<<iter->n<<", "<<iter->str<<" --> ";
  }
  std::cout<<"\n";
  return 0;
}

В конструкторе копирования или в операторе назначения копирования я просто передаю список, который имеет дискретную памятьраспределение.Как это возможно, что передача только a.pll в моей семантике перемещения перемещает всю память к следующему объекту?Я ожидал, что мне нужно пройти через каждый из объектов списка и затем переместить их.

Но нет. Это просто работает как магия, просто перемещая a.pll к другому объекту.Как происходит внутри?

Вы можете увидеть это в действии здесь: https://repl.it/repls/WildComfortableLesson

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Это потому, что std::list реализует для вас назначение перемещения .

Кстати, конструктор перемещения можно немного улучшить, используя списки инициализаторов:

Node(Node&& n) : ll{std::move(n.ll)}, pll{std::move(n.pll)} {}

Это приведет к построению двух списков (с использованием конструктора перемещения std::list) вместо построения по умолчанию, а затем к перемещению, назначая их.То же самое относится и к конструктору копирования.

0 голосов
/ 24 сентября 2019

Я вижу, что создается Node m, который содержит два пустых списка.Список 1 содержит целые числа. Список 2 содержит целые и строковые значения.Затем, когда вы вызываете функцию CreateNode, она просто проходит через пустой узел и присваивает значения одно за другим (см. Функцию создания узла) (возможно, для этого использовался бы цикл, но вместо этого в этой реализации они просто выталкивали один за другим (одно и то же)),Затем они печатают значения.

Я надеюсь, что это помогает ура.

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