void fun() { // Allocation d'un objet de type A confié au pointeur intelligent sp unique_ptr<A> sp(new A()); ... // Utilisation de l'objet par l'intermédiaire de sp *sp ... // La destruction de la variable sp libère l'objet de type A }
// Maximum de deux entiers int max(int m, int n) { return m > n ? m : n; } // Maximum de trois entiers int max(int m, int n, int p) { return m > n ? (m > p ? m : p) : (n > p ? n : p); } // Maximum de deux flottants float max(float x, float y) { return x > y ? x : y; } // Programme principal int main() { cout << max(2, 3) << endl; cout << max(2, 4, 3) << endl; cout << max(2.3, 3.2) << endl; }
// Classe avec toutes les méthodes fournies par défaut class A { private: int v; }; // Utilisation du constructeur de copie pour initialiser le paramètre A fun(A a) { return a; // Utilisation du constructeur de copie } // pour copier la valeur de retour int main() { A a; // Utilisation du constructeur par défaut A b = a; // Utilisation du constructeur de copie b = a; // Utilisation de l'opérateur d'affectation b = fun(a); // Utilisations multiples // Utilisation du destructeur par défaut pour détruire a et b }Depuis la version C++11, il y aussi les méthodes suivantes.
class A { friend class F; // Classe F déclarée amie de la classe A public: A(int v) : val(v) {} // Constructeur int get() { return val; } // Méthode publique de A accédant à l'attribut privé val de A private: int val; // Attribut privé de A }; class F { public: F(int v) : val(v) {} // Constructeur // Utilisation normale d'une méthode publique de A int get(A a) { return val = a.get(); } // Accès à un attribut privé de A void set(A& a) { a.val = val; } private: int val; }; int main() { A a(-1); F f(1); f.set(a); cout << a.get() << endl; }
class A { public: // Méthode applicable à un objet constant void change() const { m++; } private: int n = 0; // Attribut non modifiable par change mutable int m = 0; // Attribut modifiale }; int main() { const A a; // Object constant a.change(); }
class B { // Classe de base public: // Méthode non virtuelle void nprint() { cout << "B" << endl; } // Méthode virtuelle virtual void vprint() { cout << "B" << endl; } }; class D : public B { // Classe dérivée public: // Redéfinition de la méthode non virtuelle void nprint() { cout << "D" << endl; } // Redéfinition de la méthode virtuelle void vprint() { cout << "D" << endl; } }; // Appel des deux méthodes nprint et vprint sur un objet void print(B& b) { b.nprint(); b.vprint(); } int main() { B b; // Objet de type B D d; // Objet de type D print(b); // Affiche B et B print(d); // Affiche B et D }
class B { // Classe de base public: virtual ~B() = 0; // Destructeur virtuel pur };Le problème est qu'une telle classe B ne peut pas être utilisée. D'une part, elle ne peut pas être instanciée car son destructeur est virtuel. D'autre part, toute classe qui dérive directement ou non de B ne peut pas être instanciée non plus car son destructeur doit appeler le destructeur de sa classe de base qui n'existe pas. Pour que B ou une classe dérivée de B puissent être instanciée, il est possible d'ajouter une définition par défaut du destructeur tout en le laissant virtuel pur.
B::~B() { ... }Dans ce cas, le fait d'être virtuel pur pour le destructeur n'a plus d'intérêt car un destructeur n'est pas hérité par une classe dérivée.