#include <iostream> // `cin', `cout' et `cerr'.
#include <iomanip>  // setw(...).

using namespace std ;

class Objet {
	string nom ;
public :
	// Constructeur par défaut.
	Objet() : nom("<non initialisé>") {
		cout << "Appel du constructeur par défaut    -- " << nom << endl ; }
	// Constructeur de copie.
	Objet(const Objet & arg) : nom("copie de " + arg.nom) {
		cout << "Appel du constructeur de copie      -- " << nom << endl ; }
	// Constructeur normal.
	Objet(const string & arg) : nom(arg) {
		cout << "Appel du constructeur avec argument -- " << nom << endl ; }
	// Destructeur.
	~Objet() {
		cout << "Appel du destructeur -- " << nom << endl ; }
	// Opérateur d'affectation.
	Objet & operator=(const Objet & arg) {
		cout << "Appel de l'opérateur d'affectation -- " << arg.nom << endl ;
		nom = "affectation de " + arg.nom ; }
} ;
void
num_ligne(const size_t & num)
{
	cout << "Ligne " << setw(2) << num << ' ' ;
}
int
main()
{
	// Appel du constructeur normal.
	num_ligne(__LINE__) ; Objet premier("`Ceci est mon objet'") ;
	// Première syntaxe de l'appel du constructeur par défaut.
	{ num_ligne(__LINE__) ; Objet second ; }
	// Deuxième syntaxe de l'appel du constructeur par défaut.
	{ num_ligne(__LINE__) ; Objet second = Objet() ; }
	// Syntaxe pour déclarer la fonction `second', sans argument, qui retourne un `Objet'.
	{ num_ligne(__LINE__) ; Objet second() ; cout << endl ; }
	// Première syntaxe de l'appel du constructeur de copie.
	{ num_ligne(__LINE__) ; Objet second(premier) ; }
	// Deuxième syntaxe de l'appel du constructeur de copie.
	{ num_ligne(__LINE__) ; Objet second = premier ; }
	// Troisième syntaxe de l'appel du constructeur de copie.
	{ num_ligne(__LINE__) ; Objet second = Objet(premier) ; }
	// Appel de l'opérateur d'affectation.
	Objet second ; second = premier ;
	return 0 ; // Retour au système d'exploitation avec le code `0'.
}
