#include <iostream>
#include <cmath>
#include <string.h>

using namespace std;

class Vector {
    int *tableau;

    public:
        Vector(int a = 0, int b = 0, int c = 0);
        ~Vector();
        void fillTableau(int v[]);
        void setTableau(int newTableau[]);
        friend istream& operator>>(istream& is, Vector& v1);
        friend ostream& operator<<(ostream& os, const Vector& v1);
        Vector& operator= (const Vector& v);
};

Vector::Vector(int a, int b, int c) {
    tableau = new int[3];
    tableau[0] = a;
    tableau[1] = b;
    tableau[2] = c;
}

Vector::~Vector() {
    delete [] tableau;
}

void Vector::fillTableau(int v[]) {
    for (int i = 0; i<3; i++) {
        v[i] = tableau[i];
    }
}

void Vector::setTableau(int newTableau[]) {
    for (int i = 0; i<3; i++) {
        tableau[i] = newTableau[i];
    }
}

Vector operator+(Vector v1, Vector v2) {
    Vector resultat;

    // Création des pointeurs de résultat
    int *newTableau = new int[3];
    int *v1tab = new int[3];
    int *v2tab = new int[3];

    // On récupère les vecteurs v1 et v2 pour les stocker localement
    v1.fillTableau(v1tab);
    v2.fillTableau(v2tab);

    // On remplit le nouveau tableau local
    for (int i = 0; i<3; i++) {
        newTableau[i] = v1tab[i] + v2tab[i];
    }

    // On injecte le tableau local dans l'instance résultat
    resultat.setTableau(newTableau);

    // Suppression des éléments créés dynamiquement
    delete [] newTableau;
    delete [] v1tab;
    delete [] v2tab;

    return resultat;
}

Vector operator-(Vector v1, Vector v2) {
    Vector resultat;

    // Création des pointeurs de résultat
    int *newTableau = new int[3];
    int *v1tab = new int[3];
    int *v2tab = new int[3];

    // On récupère les vecteurs v1 et v2 pour les stocker localement
    v1.fillTableau(v1tab);
    v2.fillTableau(v2tab);

    // On remplit le nouveau tableau local
    for (int i = 0; i<3; i++) {
        newTableau[i] = v1tab[i] - v2tab[i];
    }

    // On injecte le tableau local dans l'instance résultat
    resultat.setTableau(newTableau);

    // Suppression des éléments créés dynamiquement
    delete [] newTableau;
    delete [] v1tab;
    delete [] v2tab;

    return resultat;
}

Vector operator*(Vector v1, Vector v2) {
    Vector resultat;

    // Création des pointeurs de résultat
    int *newTableau = new int[3];
    int *v1tab = new int[3];
    int *v2tab = new int[3];

    // On récupère les vecteurs v1 et v2 pour les stocker localement
    v1.fillTableau(v1tab);
    v2.fillTableau(v2tab);

    // On remplit le nouveau tableau local
    for (int i = 0; i<3; i++) {
        newTableau[i] = v1tab[i] * v2tab[i];
    }

    // On injecte le tableau local dans l'instance résultat
    resultat.setTableau(newTableau);

    // Suppression des éléments créés dynamiquement
    delete [] newTableau;
    delete [] v1tab;
    delete [] v2tab;

    return resultat;
}

Vector& Vector::operator= (const Vector& v) {
    if (&v != this) {
        tableau[0] = v.tableau[0];
        tableau[1] = v.tableau[1];
        tableau[2] = v.tableau[2];
    }
    return *this;
}

ostream& operator<<(ostream& os, const Vector& v1) {
    os << v1.tableau[0] << " " << v1.tableau[1] << " " << v1.tableau[2] << endl;

    return os;
}

istream& operator>>(istream& is, Vector& v1) {
    cout << "Rentrez les 3 composantes du vecteur" << endl;
    is >> v1.tableau[0] >> v1.tableau[1] >> v1.tableau[2];

    return is;
}

int main()
{
    Vector v1;
    cin >> v1;
    cout << v1;

    Vector v2;
    cin >> v2;
    cout << v2;

    Vector addition;
    addition = v1 + v2; // On teste l'auto affectation
    cout << "v1 + v2 = " << addition;

    Vector v3;
    cin >> v3;
    cout << v3;

    Vector v4;
    cin >> v4;
    cout << v4;

    Vector soustraction;
    soustraction = v3 - v4;
    cout << "v3 - v4 = " << soustraction;

    Vector v5;
    cin >> v5;
    cout << v5;

    Vector v6;
    cin >> v6;
    cout << v6;

    Vector multiplication = v5 * v6;
    cout << "v5 * v6 = " << multiplication;

    return 0;
}
