#include #include using namespace std; // utilisation de la méthode #define INTERN 0 #define EXTERN 1 /* g++ -std=c++14 dev_surcharge.cpp -D OP_PLUS_EXT=0 -o dev_surcharge // INTERN g++ -std=c++14 dev_surcharge.cpp -D OP_PLUS_EXT=1 -o dev_surcharge // EXTERN */ // #define OP_PLUS_EXT BOTH // #define BOTH 7 // BOTH les deux !! (test pour connaître le choix du compilo) // error: use of overloaded operator '+' is ambiguous // (with operand types 'Test' and 'Test') class Test { private: int val; string name; public: Test (string s="default", int v=-1); Test (Test const&); ~Test (); ostream& affiche (ostream& sortie) const; // surcharge interne Test& operator+= (Test const&); Test& operator= (Test const&); #if OP_PLUS_EXT == INTERN Test const operator+ (Test const&); #endif }; ostream& operator<<(ostream&, Test const&); Test::Test (string s, int v) // : name (s), val (v) { cout << "NEW val : " << *this << endl; } Test::Test (Test const& t) : name( t.name+"_dup"), val( t.val) { cout << "DUP val : " << t << endl; } Test::~Test () { cout << "DEL val : " << name << " " << val << endl; } Test& Test::operator= (Test const& t) { cout << "OP = : " << *this << " = " << t << endl; name = name +"="+t.name; val = t.val; return *this; } Test& Test::operator+= (Test const& t) { cout << "OP+= : " << *this << " += " << t << endl; val += t.val; name = name+"+="+t.name; cout << "OP+= END : " << *this << endl; return *this; // utile pour affectation à la suite : t3 = (t1+=t2); // renvoie alors &t1 pour affectation dans t3 // pas la peine de créer une copie locale car t1 existe déjà } #if OP_PLUS_EXT == EXTERN Test const operator+(Test, Test const&); Test const operator+ (Test t1, Test const& t2) { cout << "OP+ EXT : " << t1 << t2 << endl; t1 += t2; // passage par une méthode -> interne return t1; } #else Test const Test::operator+ (Test const& t) { cout << "OP+ INT : " << *this << t << endl; // ERROR ??? Test tmp; tmp.val = val + t.val; tmp.name = name+"+"+t.name; return tmp; } #endif ostream& Test::affiche(ostream& sortie) const { sortie << "(" << name << " : " << val << ")"; return sortie; } ostream& operator<<(ostream& sortie, Test const& t) { return t.affiche( sortie); } // /* // ces deux fonctions pour vérifier que cout << t; // s'excute sans erreur dans une fonction // */ // void display_ref(Test &); // void display_ref(Test &t){ // cout << "display ref " << t << endl; // } // // void display_val(Test); // void display_val(Test t){ // cout << "display val " << t << endl; // } int main() { Test t1("t1",1); Test t2("t2",2); cout << t1 << t2 << endl; // Test t3(t2); // cout << t3 << endl; // cout << "display_ref" << endl; // display_ref(t1); // cout << "display_val" << endl; // display_val(t1); // cout << "end display" << endl; cout << "TEST1 + " << endl; cout << "** " << (t1+t2) << " **" << endl; // cout << "TEST2 + " << endl; // Test t4("t4", 16); // cout << t4 << endl; // cout << "** " << (t4 = (t1+t2)) << " **" << endl; // cout << t4 << endl; // cout << "TEST1 =" << endl; // OK // Test t5("t5", 5); // // t5 += t1; // cout << t5 << endl; // t5 = t1; // cout << t5 << endl; // cout << (t5 = t2) << endl; // cout << "TEST2 +=" << endl; // t4 = {"aze", 13}; // cout << t4 << endl; cout << "END" << endl; return 0; }