FAQ C++/CLI et VC++.NetConsultez toutes les FAQ

Nombre d'auteurs : 29, nombre de questions : 248, création le 22 février 2013 

 
OuvrirSommaireLe langage C++/CLIClasses, Interfaces, héritage et types de données

On définit en C++/CLI une classe virtuelle pure en utilisant le mot clé sensible au contexte abstract (voir Qu'est-ce qu'une fonction virtuelle pure ? dans la faq c++).
Ainsi, l'utilisation d'abstract indique qu'une classe et ses membres abstraits peuvent être uniquement définis dans une classe dérivée et ne pourront pas être instanciés (seulement servir de classe de base).
On déclare une classe virtuelle pure ainsi :

 
Sélectionnez

ref class c abstract
{
public:
	virtual void f() abstract;
};
				
Créé le 12 juillet 2006  par nico-pyright(c)

Lien : Qu'est-ce qu'une fonction virtuelle pure ? dans la faq c++

On utilise le mot clé sensible au contexte override pour préciser explicitement que l'on surcharge une méthode (abstraite ou virtuelle).

 
Sélectionnez

ref class c abstract
{
public:
	virtual void f() abstract;
};
 
ref class d : c
{
public:
	virtual void f() override
	{
		// implémentation
	}
};
				

Il s'agit ici d'une surcharge implicite.

Créé le 12 juillet 2006  par nico-pyright(c)

On utilise le mot clé sensible au contexte sealed pour indiquer qu'une classe ou une méthode ne peut pas être dérivée.
Ainsi, dans l'exemple suivant, la méthode f de la casse c ne peut être surchargée, et provoque ainsi une erreur de compilation :

 
Sélectionnez

ref class c
{
public:
   virtual void f() sealed 
   {
      System::Console::WriteLine("f ne pourra pas être dérivée");
   }
};
 
ref class d : public c 
{
public:
   virtual void f() override  // erreur du compilo
   {
      // ....
   }
};
				
 
Sélectionnez

error C3764: 'd::f': cannot override base class method 'c::f'

On définit une classe sealed de la même facon :

 
Sélectionnez

ref class c sealed
{
public:
   void f()
   {
      // ...
   }
};
 
ref class d : public c  // erreur
{
 
};

Ici on obtiendra l'erreur de compilation suivante :

 
Sélectionnez

error C3246: 'd' : cannot inherit from 'c' as it has been declared as 'sealed'
				
Créé le 12 juillet 2006  par nico-pyright(c)

On utilise le mot clé sensible au contexte new pour indiquer qu'une fonction ne surcharge pas une méthode d'une classe mère.
Ainsi l'exemple suivant :

 
Sélectionnez

ref class Animal
{
public :
	virtual void QuiSuisJe()
	{
		Console::WriteLine("Je suis un animal");
	}
};
 
ref class Dog : Animal
{
public :
	virtual void QuiSuisJe() override
	{
		Console::WriteLine("Je suis un chien");
	}
};
 
ref class Cat : Animal
{
public :
	virtual void QuiSuisJe() new
	{
		Console::WriteLine("Je suis un chat");
	}
};
 
int main() 
{
	Animal ^an1 = gcnew Animal();
	Animal ^an2 = gcnew Dog();
	Animal ^an3 = gcnew Cat();
 
	an1->QuiSuisJe();
	an2->QuiSuisJe();
	an3->QuiSuisJe();
}
				

produira le resultat suivant :

 
Sélectionnez

Je suis un animal
Je suis un chien
Je suis un animal

On constate bien que l'objet Animal (Cat) ne peut pas utiliser la méthode QuiSuisJe() de la classe Cat, celle-ci n'étant pas la surcharge de la méthode QuiSuisJe de la classe Animal, à contrario de la classe Dog.

Créé le 12 juillet 2006  par nico-pyright(c)

Un constructeur de copie instancie un objet en créant une copie d'un autre objet. Alors qu'en C++, un constructeur de copie par défaut est généré automatiquement, en C++/CLI ce n'est pas le cas.
Considérons l'exemple suivant :

 
Sélectionnez

ref class Personne
{
private:
	String ^nom;
	String ^prenom;
public:
	Personne(String ^n, String ^p) : nom(n), prenom(p){}
	Personne(const Personne^ p) : nom(p->nom), prenom(p->prenom){}
};
 
// exemple d'appel
Personne ^p1 = gcnew Personne("nico", "pyright");
Personne ^p2 = gcnew Personne(p1);

Nous avons ainsi défini un constructeur de copie.

NB : Une limitation de cet exemple est qu'on ne peut utiliser le constructeur de copie qu'avec des handles d'objet, et non avec un objet lui même.
L'exemple suivant produit une erreur de compilation :

 
Sélectionnez

	Personne p3("nico", "pyright");
	Personne ^p4 = gcnew Personne(p3); // erreur de compilation C3073

Pour contourner ce problème, on peut utiliser l'opérateur de référence %.

 
Sélectionnez

	Personne p3("nico", "pyright");
	Personne ^p4 = gcnew Personne(%p3);

NB : Une autre solution pourrait être de définir un autre constructeur de copie utilisant une référence, mais cela entraine une duplication de code.
On pourrait bien sûr déporter l'initialisation dans une méthode privée, mais cela nous priverait d'utiliser les listes d'initialisations.

Créé le 27 mars 2007  par nico-pyright(c)

Un opérateur d'affectation permet d'affecter un objet à un autre. Il est généré automatiquement en C++ natif, en C++/CLI il faut le spécifier manuellement.
Dans l'exemple précédent, l'affectation suivante :

 
Sélectionnez

	Personne p1("nico", "pyright");
	Personne p2("", "");
	p2 = p1;

Aurait généré l'erreur de compilation C2582 ('operator =' function is unavailable).
Pour y remédier, on définit l'opérateur d'affectation, comme en C++ classique :

 
Sélectionnez

	Personne% operator=(const Personne% p)
	{
		if(%p == this)
			return *this;
		nom = p.nom;
		prenom = p.prenom;
		return *this;
	}

Il ne faut bien sûr pas oublier de tester si on est pas en train d'affecter le même objet.

NB : L'opérateur d'affectation est visible uniquement par des clients C++/CLI, et non depuis des langages comme C# ou VB.Net.
On prendra garde de même à ne pas confondre avec l'affectation de handles vers les objets managés.

Créé le 27 mars 2007  par nico-pyright(c)
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006-2007 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.