mardi 24 septembre 2019

Moving object of lists in C++ to another object

I'm trying to understand how this piece of code is working.

// 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;
}

In the copy constructor or in the copy assignment operator, I'm just passing the list, which has a discrete memory allocation. How is it possible that passing only the a.pll in my move semantics moves the whole lot of the memory to the next object? I expected I need to go though each of the list objects and then move them across.

But No. It is simply working like magic, just by moving a.pll to other object. How is going on internally?

You can see this in action here: https://repl.it/repls/WildComfortableLesson

Aucun commentaire:

Enregistrer un commentaire