|
Droit de
diffusion: L'ensemble ou partie
de ce document ainsi que le code mis à disposition, ne peut être
diffusé sur d'autres sites Web sans l'autorisation au préalable de
son créateur.
Certaines parties de cet
article sont extraites de l'article : "C++ -> C#: What You Need to
Know to Move from C++ to C#" de Jesse Liberty.
Avant
Propos : Ce document a pour but de
présenter les principales différences entre le C++ et le C# et
d'aider les personnes désireuses de réaliser le portage d'une
application C++ en C#.
Sommaire:
Introduction 1. Les
pièges 2. Les principales différences entre le C++ et le
C# 3. Les types de valeur et de référence 4. Les structures 5. Tout dérive de
la classe Object 6. La gestion des paramètres
des prototypes de fonctions 7. Le mot clé "new" 8. Les propriétés 9. Les
tableaux Conclusion
Introduction
Le langage C# s'appuit sur la
syntaxe et la sémantique du C++, permettant au programmeur C de
bénéficier des avantages de .NET et de la Common Language Runtime.
Alors que la transition du C++ vers le C# peut paraître aisée, il y
a un certain nombre d'éléments qui ont changé que nous allons
étudier tels que l'opérateur new, les structures, les constructeurs,
les destructeurs.
1. Pièges
Le langage C# ressemble à s'y
méprendre au C++. Il se peut que vous écriviez du code qui
est parfaitement correct en C++ mais qui ne compile pas en C#
ou au pire ne se comporte pas à l'exécution comme vous
l'attendiez. La plupart des différences syntaxiques entre
le C++ et le C# sont triviales (pas de point virgule après la
déclaration d'une classe, Main comporte désormais une majuscule) et
sont détectées par le compilateur.
2. Les principales différences entre le C++
et le C#
| Fonctionnalité |
Documentation de
référence |
|
Héritage : Une classe peut hériter de
l'implémentation d'une seule classe de base uniquement. Une
classe ou une interface peuvent implémenter plusieurs
interfaces. |
class
interface |
| Tableaux: La déclaration
d'un tableau en C# est différente de celle en C++. Les
crochets "[]" doivent apparaître à la suite du type de
tableau en C#. |
Arrays |
| Le type bool: Il n'existe pas de
conversion entre le type bool et d'autres types
(particulièrement int). |
bool |
| Le type long : En C#, le
type de données long est
sur 64 bits alors qu'il est sur 32 bits en C++. |
long |
| Le type struct : En C#, les
classes et les structures sont sémantiquement différents. Une
structure est un type de valeur alors qu'une classe est un
type de reference. |
struct
class |
| L'instruction switch : Comparativement au C++, le
C# n'autorise pas le passage automatique à chaque condition
d'une clause switch. |
switch |
| Le type delegate : Les delegates ressemblent
à des pointeurs de fonctions mais ils sont sécurisés et
fortement typés. |
delegate |
|
Appel d'une fonction membre d'une
classe surchargée à partir d'une classe dérivée. |
base
Voir aussi les exemples pour override |
|
Utilisation du mot clé New afin de
cacher explicitement une fonction héritée. |
new |
|
La surcharge d'une méthode nécessite
l'utilisation du mot clé override
|
override |
|
Les directives de préprocessing sont
utilisées pour la compilation conditionnelle. Il n'y pas de
fichier includes en C#. |
C# Preprocessor
Directives |
| La gestion des
exceptions: L'utilisation de la clause finally. |
try-finally
try-catch-finally |
| Les opérateurs C# : Le C#
comporte des opérateurs supplémentaires tels que is et typeof ainsi que des
fonctionnalités différentes de certains opérateurs
logiques. |
& Operator
| Operator
^ Operator
is
typeof |
| L'utilisation du mot clé
extern |
extern |
| L'utilisation du mot clé
static |
static |
|
Une solution alternative à la liste
d'initialisation C++ dans la construction d'une classe de
base. |
Voir les
exemples pour virtual |
| La structure générale
d'un programme C#: les espaces de noms, les classes, les
structures, les delegates, les énumérations. |
General Structure of a C#
Program |
|
La déclaration de la méthode Main diffère de celle en C++
mais aussi la manipulation des arguments passés en ligne de
commande. |
Main |
| Les paramètres des
méthodes: Le C# supporte les mots réservés ref et out , qui sont utilisés à la place de
pointeurs pour le passage de paramètre par référence. |
ref
out |
| Les pointeurs sont
autorisés en C# mais seulement dans un mode dit "unsafe". |
unsafe |
| La surcharge d'opérateurs
est différente en C# |
C# Operators |
| Les chaînes de caractères
C# sont différentes de celles en C++ |
string |
|
Le mot clé foreach permet de parcourir des
tableaux et des collections. |
foreach, in |
| Il n'existe pas de
méthodes ou de variables globales en C#: Les
méthodes et les variables doivent être contenues dans
la portée d'une déclaration (tel qu'une classe ou une
structure) |
General Structure of a C#
Program |
|
Il n'existe pas de fichiers entêtes ou
de directives d'inclusions en C#: Le mot clé using est utilisé pour référencer des
espaces de noms. |
using |
| Les variables
locales en C# ne peuvent être utilisées sans avoir été
initialisées au préalable. |
5. Variables |
| Les destructeurs : En C#
il n'est pas possible de maîtriser l'appel de
destructeurs car ceux-ci sont appelés automatiquement par
le ramasse miettes (garbage collector). |
Destructors |
| Les
constructeurs: Comparativement au C++, si vous ne
fournissez pas un constructeur, un constructeur par défaut est
automatiquement généré. Celui-ci se charge d'initialiser tous
les champs avec leurs valeurs par défaut. |
Instance Constructors
Default Values
Table. |
|
Le C# ne supporte pas les champs de
type "bit". |
C++ Bit Fields |
|
Les services d'entrée/sortie et de
formattage de données s'appuient sur le RunTime du Framework
.NET. |
C# Language Tour
Formatting Numeric Results
Table |
| En C# les paramètres des
méthodes ne peuvent avoir de valeur par défaut. Il faut
surcharger les méthodes pour obtenir ce résultat. |
Compiler Error
CS0241 |
3. Les types de valeur et de référence
Le C# distingue les types de valeur (value) des
types de référence (reference). Les types simples (int, long, double
...) et les structures sont des types de valeurs alors que les
classes sont des types de référence tout comme les objets. Les types
value représentent la donnée réelle
stockée sur la pile et sont passés aux méthodes par valeur (une
copie est réalisée). Les types reference contiennent l'adresse d'un objet
stocké sur le tas et sont passés en paramètre par
référence.
4. Les structures
Les
structures sont différentes en C#. En C++ les structures sont
exactement comme une classe, sauf que l'héritage et l'accès par
défaut est public et non privé. En C# les structures sont
conçues pour encapsuler de petits objets et sont de type value (donc passées par valeur). Elles
sont limitées dans la mesure où elles ne peuvent dériver d'aucune
classe sauf System.ValueType et qu'elles ne peuvent pas définir de
constructeur par défaut (sans paramètres). En contre partie
l'utilisation d'une structure est préférable à celui d'une classe
pour de trés petits objets.
5. Tout dérive de la classe Object
En C# finalement tout dérive de la classe
Object aussi bien les classes que vous créez que les types de
valeurs (int, struct ...). La classe Object présente des méthodes
utiles comme la méthode ToString. Prenons un exemple d'utilisation
de la méthode ToString et de la méthode System.Console.WriteLine
(équivalent du cout en C++). Considérons un objet myEmployee comme
instance de l'objet Employee et un objet myCounter comme instance de
l'objet Counter. Si nous écrivons le code suivant :
Console.WriteLine("The
employee: {0}, the counter value: {1}", myEmployee,
myCounter);
|
La méthode WriteLine va appeler
la méthode virtuelle Objet.ToString de chacun de ces objets et
substituer les chaînes que les paramètres vont retourner. Si la
classe Employee ne surcharge pas la méthode ToString
l'implémentation par défaut sera appelée laquelle retourne le nom de
la classe. La classe Counter va surcharger la méthode ToString afin
de retourner un entier ce qui produit à l'exécution le résultat
suivant :
The employee: Employee,
the counter value: 12
|
Que se passe-t-il si l'on
transmet à la méthode WriteLine un entier ? Il n'est pas possible
d'appeler la méthode ToString sur un entier mais le compilateur va
implicitement transformer l'entier en une instance de l'objet Object
dont la valeur sera celle de l'entier. Cette transformation porte le
terme de boxing.
Vous trouverez ci-joint l'exemple
complet.
6. La gestion des paramètres des prototypes
de fonctions
En C# comme en C++ une méthode ne peut avoir
qu'une seule valeur en retour. Pour pallier à cette limitation en
C++ les paramètres sont passés par références ou via des pointeurs.
La méthode appelée change la valeur des paramètres et les rend
accessibles à la méthode appelante. En C# quand vous passez une
référence à une méthode vous avez accès à l'objet d'origine, comme
en C++ avec le passage par référence ou les pointeurs. En revanche
cela ne fonctionne pas avec les types de valeurs. Si vous souhaitez
passer un type de valeur par reference alors il faut le faire
précéder du mot clé ref.
Il est important de préciser que
le mot réservé ref doit être utilisé aussi bien dans la déclaration
de la méthode que dans la méthode appelante.
| Fred.GetStats(ref age, ref ID,ref yearsServed);
|
Vous pouvez maintenant déclarer
les champs age,ID,yearsServed dans la méthode appelante et les
passer à la méthode GetStats et récupérer les valeurs modifiées en
retour.
En C# il est
nécessaire d'initialiser les variables avant de les passer à la
méthode GetStats (definite assignment). Il est possible d'éviter
cette initialisation en utilisant le mot clé out. En utilisant le mot clé out en
C#, vous indiquez que la variable n'est pas initialisée et qu'elle
est passée par référence.
| Fred.GetStats(out age, out ID,out yearsServed);
|
Comme lors de l'utilisation du
mot clé ref, le mot clé out doit être utilisé aussi bien dans la
déclaration de la méthode que dans la méthode appelante.
| Fred.GetStats(out age,out ID,out yearsServed);
|
7. Le mot clé "new"
En C++, le mot clé New instancie
un objet sur le tas. Le langage C# fait de même avec les types de
reference. Pour les types de valeurs comme les structures, l'objet
est créé sur la pile et un constructeur est appelé.
Vous pouvez aussi créer une
structure sur la pile sans utiliser le mot clé New, mais attention
car New initialise l'objet. Ce qui veut dire que toutes les valeurs
de structure doivent être initialisées à la main (avant le passage à
une méthode).
8. Les propriétés
En C++, les programmeurs essaient
de garder les variables membres privées. C'est le principe même de
l'encapsulation qui permet de modifier l'implémentation d'une classe
sans en changer l'interface. Concrètement, le développeur C++ va
créer des accesseurs permettant de modifier les valeurs de variables
membres privées.
En C#, les propriétés sont les
premiers membres d'une classe. Pour un client, une propriété
ressemble à une variable membre mais pour le développeur de la
classe il s'agit plutôt d'une méthode. Les propriétés
favorisent l'encapsulation et offrent au client un accès
facilité aux membres de la classe.
Par exemple considérons une
classe Employee avec une propriété Age permettant à un client
de valoriser ou d'extraire l'age d'une employé.
Le mot clé value est défini implicitement au
travers de la propriété. Si vous écrivez
le compilateur va attribuer à value la valeur 17.
Il est possible d'implémenter une
propriété en lecture seule, il suffit de ne pas implémenter
d'accesseur Set .
9. Les tableaux
Le C# propose une classe de
gestion des tableaux plus complète que le tableau traditionnel
C/C++. Par exemple, il est impossible d'écrire en dehors des
limites d'un tableau. De plus C# propose une classe ArrayList dont
la taille peut grossir dynamiquement en fonction des besoins du
programme.
Il existe trois types de tableaux
: unidimensionnel, multidimensionnel et des tableaux de tableaux
(jagged array).
Vous pouvez créer un tableau à
une dimension de la manière suivante :
ou l'initialiser ainsi :
| int[] myIntArray = { 2, 4, 6, 8, 10
}; |
Vous pouvez créer un tableau à
deux dimensions de la manière suivante :
| int[,] myRectangularArray = new int[rows, columns];
|
ou l'initialiser ainsi :
| int[,] myRectangularArray = {
{0,1,2}, {3,4,5}, {6,7,8}, {9,10,11} };
|
Comme les jagged array sont des
tableaux de tableaux il est nécessaire de fournir uniquement une
seule dimension.
et ensuite de créér chacun des
tableaux internes :
Parce que les tableaux dérivent
de l'objet System.Array, ils disposent de nombreuses méthodes parmis
lesquelles Sort et Reverse .
Conclusion
A travers cet article nous avons abordé les
principales différences entre le C# et le C++. Il en ressort que le
passage au C# pour un développeur C++ expérimenté devrait se faire
sans trop de difficultés la syntaxe se rapprochant beaucoup entre
ces deux langages. Attention toutefois à ne pas tomber dans la
facilité et à programmer en C# comme vous le feriez en C++ au risque
d'avoir des comportements inattendus.
Remarque
: Il est tout à fait possible qu'il y
ait des erreurs dans le document. Si vous en trouvez, ou bien
souhaitez un peu plus d'explication sur certains points, veuillez
m'envoyer un message privé via le forum afin de mettre à jour
l'ensemble de ce document. D'avance merci.
Document réalisé par Leduke |