Utilizzare il costruttore di copia in C++

Jinku Hu 12 ottobre 2023
  1. Utilizzare il costruttore di copia per inizializzare un oggetto da un altro oggetto dello stesso tipo in C++
  2. Utilizzare l’operatore di assegnazione di copia per definire l’overload dell’operatore di assegnazione per l’oggetto in C++
Utilizzare il costruttore di copia in C++

Questo articolo spiega diversi metodi su come utilizzare un costruttore di copie in C++.

Utilizzare il costruttore di copia per inizializzare un oggetto da un altro oggetto dello stesso tipo in C++

Ci sono diverse operazioni nella classe chiamate collettivamente controllo della copia. Queste operazioni definiscono come gli oggetti di un dato tipo di classe vengono copiati, spostati, assegnati o distrutti. In questo articolo, ci concentreremo solo sul costruttore di copie e sull’assegnazione di copie.

Il costruttore di copie inizializza l’oggetto duplicando il valore dell’argomento passato come riferimento (è comunemente passato come riferimento const). Non è necessario che la classe definisca il costruttore di copia come qualsiasi altra operazione di controllo della copia perché il compilatore definisce automaticamente le operazioni sintetizzate per quelle non definite. Tuttavia, spesso questi ultimi potrebbero causare problemi. Il costruttore di copie sintetizzate copia ogni membro dell’oggetto argomento nell’oggetto che viene creato. Potrebbero esserci membri di altri tipi di classe, che vengono copiati dal rispettivo costruttore di copie. Al contrario, gli oggetti di tipo incorporati vengono copiati direttamente.

Il codice di esempio seguente mostra il comportamento del costruttore di copie di MyClass, che accetta l’unico argomento obbligatorio per il costruttore di copie e quindi inizializza i membri dei dati. D’altra parte, il costruttore di copie può avere argomenti aggiuntivi, che devono essere facoltativi e avere valori predefiniti.

Quando viene inizialmente creato l’oggetto di tipo MyClass, viene invocato il costruttore di default; tuttavia, se assegniamo m1 alla variabile m3 appena creata, viene chiamato il costruttore di copie. Quest’ultima operazione è anche chiamata inizializzazione della copia, che può utilizzare un costruttore di copie o spostare un costruttore (discusso in un altro articolo).

#include <iostream>

using std::cout;
using std::endl;
using std::pair;

class MyClass {
 private:
  int n1{};
  int n2{};

 public:
  MyClass(int x, int y) : n1(x), n2(y) {
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& src) {
    cout << "Copy Constructor is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
  }

  auto getPair() { return pair<int, int>(n1, n2); }

  ~MyClass() = default;
};

int main() {
  MyClass m1(12, 21);
  cout << "------------------" << endl;
  MyClass m2(11, 33);
  cout << "------------------" << endl;
  MyClass m3 = m1;
  cout << "------------------" << endl;

  cout << m1.getPair().first << m1.getPair().second << endl;
  cout << m2.getPair().first << m2.getPair().second << endl;
  cout << m3.getPair().first << m3.getPair().second << endl;

  return EXIT_SUCCESS;
}

Produzione:

Constructor 1 is called-- -- -- -- -- -- -- -- --Constructor 1 is
    called-- -- -- -- -- -- -- -- --Copy Constructor is
        called-- -- -- -- -- -- -- -- --1221 1133 1221

Utilizzare l’operatore di assegnazione di copia per definire l’overload dell’operatore di assegnazione per l’oggetto in C++

L’operatore di assegnazione della copia definisce come assegnare oggetti dello stesso tipo. Il compilatore sintetizza anche questa operazione se l’utente non la definisce esplicitamente. L’assegnazione della copia è descritta in modo simile ad altre funzioni di sovraccarico dell’operatore. Prende un argomento dello stesso tipo della classe e di solito restituisce il riferimento all’operando di sinistra. Un operatore di assegnazione della copia deve essere definito come una funzione membro.

Il successivo frammento di codice aggiunge l’operatore di assegnazione della copia per MyClass e lo invoca mentre assegna l’oggetto m2 a m1.

#include <iostream>

using std::cout;
using std::endl;
using std::pair;

class MyClass {
 private:
  int n1{};
  int n2{};

 public:
  MyClass(int x, int y) : n1(x), n2(y) {
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& src) {
    cout << "Copy Constructor is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
  }

  MyClass& operator=(const MyClass& src) {
    cout << "Copy Assignment is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
    return *this;
  }

  auto getPair() { return pair<int, int>(n1, n2); }

  ~MyClass() = default;
};

int main() {
  MyClass m1(12, 21);
  cout << "------------------" << endl;
  MyClass m2(11, 33);
  cout << "------------------" << endl;
  MyClass m3 = m1;
  cout << "------------------" << endl;
  m1 = m2;
  cout << "------------------" << endl;

  cout << m1.getPair().first << m1.getPair().second << endl;
  cout << m2.getPair().first << m2.getPair().second << endl;
  cout << m3.getPair().first << m3.getPair().second << endl;

  return EXIT_SUCCESS;
}

Produzione:

Constructor 1 is called-- -- -- -- -- -- -- -- --Constructor 1 is
    called-- -- -- -- -- -- -- -- --Copy Constructor is
        called-- -- -- -- -- -- -- -- --Copy Assignment is
            called-- -- -- -- -- -- -- -- --1221 1133 1221
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook