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 ?
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);
}
}
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;
}