Il existe quelques différences dans les conventions d'appel en C++ et en Java. En C++, il n'y a techniquement que deux conventions : pass-by-value et pass-by-reference, certaines publications incluant une troisième convention pass-by-pointer (qui est en fait pass-by-value d'un type pointeur). En plus de cela, vous pouvez ajouter une constance au type de l'argument, ce qui améliore la sémantique.
Passer par référence
Le passage par référence signifie que la fonction recevra conceptuellement votre instance d'objet et non une copie de celle-ci. La référence est conceptuellement un alias de l'objet qui a été utilisé dans le contexte d'appel, et ne peut être nulle. Toutes les opérations effectuées à l'intérieur de la fonction s'appliquent à l'objet à l'extérieur de la fonction. Cette convention n'est pas disponible en Java ou en C.
Pass by value (et pass-by-pointer)
Le compilateur va générer une copie de l'objet dans le contexte d'appel et utiliser cette copie dans la fonction. Toutes les opérations effectuées à l'intérieur de la fonction sont effectuées sur la copie, et non sur l'élément externe. C'est la convention pour les types primitifs en Java.
Une version spéciale de cette méthode consiste à passer un pointeur (adresse de l'objet) dans une fonction. La fonction reçoit le pointeur, et toutes les opérations appliquées au pointeur lui-même sont appliquées à la copie (pointeur), d'autre part, les opérations appliquées au pointeur déréférencé s'appliqueront à l'instance de l'objet à cet emplacement mémoire, donc la fonction peut avoir des effets secondaires. L'effet de l'utilisation de pass-by-value d'un pointeur vers l'objet permettra à la fonction interne de modifier les valeurs externes, comme avec pass-by-reference et permettra également des valeurs optionnelles (passer un pointeur nul).
C'est la convention utilisée en C lorsqu'une fonction doit modifier une variable externe, et la convention utilisée en Java avec les types de référence : la référence est copiée, mais l'objet pointé reste le même : les modifications de la référence/pointeur ne sont pas visibles en dehors de la fonction, mais celles de la mémoire pointée le sont.
Ajouter une constante à l'équation
En C++, vous pouvez attribuer la constance aux objets lors de la définition des variables, des pointeurs et des références à différents niveaux. Vous pouvez déclarer qu'une variable est constante, vous pouvez déclarer une référence à une instance constante, et vous pouvez définir tous les pointeurs vers des objets constants, les pointeurs constants vers des objets mutables et les pointeurs constants vers des éléments constants. À l'inverse, en Java, vous ne pouvez définir qu'un seul niveau de constance (mot-clé final) : celui de la variable (instance pour les types primitifs, référence pour les types de référence), mais vous ne pouvez pas définir une référence à un élément immuable (sauf si la classe elle-même est immuable).
Cette méthode est largement utilisée dans les conventions d'appel du C++. Lorsque les objets sont petits, vous pouvez passer l'objet par valeur. Le compilateur générera une copie, mais cette copie n'est pas une opération coûteuse. Pour tout autre type, si la fonction ne modifie pas l'objet, vous pouvez passer une référence à une instance constante (généralement appelée référence constante) du type. Cela ne copiera pas l'objet, mais le transmettra à la fonction. Mais en même temps, le compilateur garantira que l'objet ne sera pas modifié dans la fonction.
Règles de base
Voici quelques règles de base à suivre :
- Préférer le pass-by-value pour les types primitifs
- Préférer le pass-by-reference avec des références à des constantes pour d'autres types
- Si la fonction doit modifier l'argument, utilisez la méthode pass-by-reference.
- Si l'argument est optionnel, utilisez le pass-by-pointer (à constant si la valeur optionnelle ne doit pas être modifiée)
Il existe d'autres petites dérogations à ces règles, la première étant le traitement de la propriété d'un objet. Lorsqu'un objet est alloué dynamiquement avec new, il doit être désalloué avec delete (ou ses versions []). L'objet ou la fonction qui est responsable de la destruction de l'objet est considéré comme le propriétaire de la ressource. Lorsqu'un objet alloué dynamiquement est créé dans un morceau de code, mais que la propriété est transférée à un élément différent, cela se fait généralement avec la sémantique pass-by-pointer, ou si possible avec des pointeurs intelligents.
Note complémentaire
Il est important d'insister sur l'importance de la différence entre les références C++ et Java. En C++, les références sont conceptuellement l'instance de l'objet, et non un accesseur à celui-ci. L'exemple le plus simple est l'implémentation d'une fonction swap :
// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
Type tmp = a;
a = b;
b = tmp;
}
int main() {
Type a, b;
Type old_a = a, old_b = b;
swap( a, b );
assert( a == old_b );
assert( b == old_a );
}
La fonction swap ci-dessus changements ses deux arguments grâce à l'utilisation de références. Le code le plus proche en Java :
public class C {
// ...
public static void swap( C a, C b ) {
C tmp = a;
a = b;
b = tmp;
}
public static void main( String args[] ) {
C a = new C();
C b = new C();
C old_a = a;
C old_b = b;
swap( a, b );
// a and b remain unchanged a==old_a, and b==old_b
}
}
La version Java du code modifiera les copies des références en interne, mais ne modifiera pas les objets réels en externe. Les références Java sont des pointeurs C sans arithmétique de pointeur qui sont transmis par valeur dans les fonctions.
7 votes
Dans quel livre apprenez-vous le C++ ?
1 votes
J'utilise Complete Reference:C++ de Herbert Schildt.
17 votes
Ce livre est fortement pas recommandé. Allez-y pour C++ Primer de Stan Lippman.
23 votes
Eh bien, voilà votre problème. Schildt est fondamentalement nul - prenez Accelerated C++ de Koenig & Moo.
4 votes
Concernant le "C++ Primer" par rapport à "Accelerated C++" : Le premier est un lourd ~1000 pages, mais il explique tout et le fait de manière très détaillée. Le second n'a que 250 pages, mais sa courbe d'apprentissage est très raide. Faites votre choix, les deux sont très recommandables.
10 votes
Je me demande pourquoi personne n'a mentionné The C++ Programming Language de Bjarne Stroustrup. Bjarne Stroustrup est le créateur de C++. Un très bon livre pour apprendre le C++.
15 votes
@George : TC++PL n'est pas pour les débutants, mais il est considéré comme l'outil le plus performant pour les débutants. Bible pour C++.xD
4 votes
Penser en C++ est plus adapté aux débutants. Et il est gratuit : mindview.net/Livres/TICPP/ThinkingInCPP2e.html
1 votes
@Daniel : Je me demande vraiment pourquoi celui-ci a été protégé. Ce n'est pas comme s'il avait accumulé une grande quantité de "merci !", "moi aussi !", ou de réponses de spam ou même de commentaires. Ou est-ce que je rate quelque chose ?