How to use operator = to copy a vector of pointers?

2

Having this class, I would implement, operator =, copy the vector from pointers to int to another vector, is it necessary to reserve memory before doing so?

What's the difference between making a builder per copy and implementing the assignment operator? Builder by copy only makes a copy of the object, while the assignment operator changes the content (in this case)?

class ints{
private:
  vector <int*> inteiros;
public: 
  ints & operator=(const ints & i1);
}
    
asked by anonymous 21.12.2016 / 22:05

2 answers

2
  

How to use operator = to copy a vector of pointers?

The operador = is already set to vector<int*>

  

Is it necessary to reserve memory before doing so?

No. Memory allocation by std::vector is automatic. Do not confuse memory for pointers with memory for integers to which pointers point to. I mean, if you copy one vector from pointers to another, both will point to the same integers.

  

What's the difference between making a builder per copy and implementing the assignment operator? Builder by copy only makes a copy of the object, while the assignment operator changes the content (in this case)?

They are different things. One is constructor and generates a new object; Another is an operator that operates on an existing object.

Generally, it is expected that when an object is created as a copy of another the result will be equal objects. That is, after we create B of the form Objeto B(A) , we expect that B==A

Generally, it is expected that when one object is assigned to another, the result is equal objects. That is, after we apply B=A , we expect that B==A

Notice that you usually expect the same result through both operations, but they are different things and you can implement each as you like.

I hope the example below is instructive, realize that I do not create either the assignment operator or the constructor. I let the compiler manage them automatically:

class ints
{
public:
  //vetor de ponteiros para int
  std::vector<int*> inteiros;
  //função que imprime valor de todos inteiros apontados
  void escreve()
  {
    for(auto i:inteiros)
      std::cout << *i << ", ";
    std::cout << std::endl;
  }
};

Creating an object ints A and saving in the vector this a few pointers:

//declara 3 ints
int x = 1;
int y = 2;
int z = 3;
//cria objeto A da classe ints
ints A;
//salva ponteiros em A 
A.inteiros.push_back(&x);
A.inteiros.push_back(&y);
A.inteiros.push_back(&z);

Creating an object by copying A :

//cria objeto B através de cópia
ints B(A);

Creating an object and using assignment to match it with A :

//cria objeto C e usa operador atribuição
ints C;
C = A;

When the content is printed, it is checked that objects point to the same x , y and z integers declared initially:

//verifica conteúdo
A.escreve();
B.escreve();
C.escreve();

(result in terminal)

1, 2, 3, 
1, 2, 3, 
1, 2, 3, 

All objects contain vectors that point to the same integers, that is, the value of the pointers saved in the vectors were all copied from A . You can check this by changing the value of any of the named integers:

//A, B e C apontam para os mesmos inteiros, incluindo y
y = 666;
//verifica-se que a mudança é visível através de todos objetos:
A.escreve();
B.escreve();
C.escreve();

(result in terminal)

1, 666, 3, 
1, 666, 3, 
1, 666, 3, 

Here is the example above online.

    
20.01.2017 / 21:14
1

Normally classes that have pointers as members need to implement 3 methods: copy constructor, assignment, and destructor.

It may also be necessary to implement the "move constructor" and "move assignment" methods, but it is rarer (this is a new feature that has entered C ++ 11).

Below is an example that implements the first 3 methods mentioned above.

This implementation does not deal with the exotic cases of copy constructor and assignment where the two operands are the same (eg "x = x").

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class IntVector
{
   public:
      vector<int*> elements;

      // default constructor   
      IntVector() { cout << "\ndefault constructor\n\n"; }

      // destructor
     ~IntVector() { cout << "\ndestructor\n"; clear(); }

      // copy constructor   
      IntVector(const IntVector& src);

      // assignment
      IntVector& operator=(const IntVector& src);

      // adiciona um elemento
      void add(int i) { elements.push_back(new int(i)); }

      // libera elementos   
     void clear();

      // imprime elementos   
      void print(const string& msg);

private:

      // copia elementos   
      void copy(const IntVector& src);
};

void IntVector::clear()
{
   cout << "liberando memoria\n";

   for (auto ptr : elements)
       delete ptr;

   elements.clear();
}

void IntVector::copy(const IntVector& src)
{
   cout << "copiando elementos\n";

   for (auto srcP : src.elements)
   {
      // cria um ponteiro e inicializa com o valor correspondente
      int* newP(new int(*srcP));
      elements.push_back(newP);
   }
}

// copy constructor
IntVector::IntVector(const IntVector& src)
{
   cout << "\ncopy constructor\n";
   copy(src);
}

// assignment
IntVector& IntVector::operator=(const IntVector& src)
{
   cout << "assignment\n";

   // libera os elementos atuais
   clear();

   // copia novos elementos
   copy(src);
}

void IntVector::print(const string& msg)
{
   cout << msg <<": [";

   for (auto p : elements)
       cout << " " << *p;

   cout << "]\n";
}


int main()
{
   // default constructor
   IntVector v1;

   v1.add(1);
   v1.add(2);
   v1.add(3);
   v1.add(4);
   v1.add(5);

   v1.print("v1");

   // copy constructor
   IntVector v2 { v1 };
   v2.print("v2");

   IntVector v3;

   // assignment
   v3 = v1;  
   v3.print("v3");
}

See working at link .

    
21.01.2017 / 00:03