Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Langages avec “copie par défaut”

En C, mais aussi en C++, une affectation est une copie.

Rappel du C

Le C est un langage qui fait une copie

struct Point {
    int x;
    int y;
}

int main() {
    Point p = {.x = 3, .y = 2};
    Point q = p;
    q.x = 100;
}

Que vaut p.x ?

Cela vaut 3.

En C++ pareil, on copie

vector<int> A = ... un vecteur de 10000000 d'éléments....
vector<int> B = A;

Oui, oui, …. B = A; est hyper looooonnnnnnng.

Attention : Python, Java, Javascript

Attention, dans des langages comme Python, Java, Javascript, les objets ne sont pas copiés car chaque variable en réalité est un pointeur. C’est uniquement le pointeur qui est copié.

  • Que fait ce programme Java ?
import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    ArrayList<String> cars = new ArrayList<String>();
    ArrayList<String> listcars = cars;
    cars.add("Volvo");
    cars.add("BMW");
    cars.add("Ford");
    cars.add("Mazda");
    System.out.println(listcars);
  }
}
Dans le programme, `cars` et `listcars` pointe vers la même `ArrayList`. Donc le programme imprime la liste des 4 voitures.

Constructeurs

Constructeur

class Point {
    public: 
        int x;
        int y;
}

int main() {
    Point p;
}

Que vaut p.x ?

p.x n’a pas été initialisé. Donc il vaut juste ce qu’il y avait à cet endroit dans la mémoire.

On peut créer un constructeur par défaut, sans paramètre.

class Point {
    public: 
        int x;
        int y;

        Point() {
            x = 0;
            y = 0;
        }
}

int main() {
    Point p;
}

Ou alors mettre des paramètres :

class Point {
    public: 
        int x;
        int y;

        Point(int ax, int ay) {
            x = ax;
            y = ay;
        }
}

int main() {
    Point p(5,2);
}

Constructeur par copie

Par défaut, quand C++ fait une “copie” des champs durant une affectation. Si vous voulez personnaliser comment fonctionne la copie, C++ en offre la possibilité avec un constructeur par copie. Un constructeur par copie prend en argument une référence vers un objet du même type. Par exemple :

class BigInt {
    BigInt(BigInt& x) {
        // là on écrit le code qui copie
    }
}

C’est le constructeur appelé si on fait :

BigInt x = ...
BigInt y = x; // ici on appelle le constructeur par copie

Exercices

  • Qu’affiche ce programme C++ ?
#include <iostream>
#include <vector>

class A {
    public:
    std::vector<int> p;
};


int main()
{
    A a;
    A b = a;
    a.p.push_back(5);
    
    std::cout << a.p.size() << std::endl;
    std::cout << b.p.size() << std::endl;

    return 0;
}
La ligne `A a;` crée un objet de type `A`. Puis `A b = a;` réalise une copie. Alors que `a.p.push_back(5);` ajoute 5 au vecteur `a.p`, le vecteur `b.p` est différent et reste vide. Donc le programme écrit 1 puis 0.