Je suis un développeur JAVA qui essaie d'apprendre le C ++, mais je ne sais pas vraiment quelles sont les meilleures pratiques pour les déclarations de fonctions standard.
Dans la classe:
class Clazz
{
public:
void Fun1()
{
//do something
}
}
Ou à l'extérieur:
class Clazz
{
public:
void Fun1();
}
Clazz::Fun1(){
// Do something
}
J'ai le sentiment que le second peut être moins lisible ...
.cpp
fichier séparé .inline
.inline
assouplit uniquement la règle d'une définition, ce qui est nécessaire si une autre unité de traduction utiliseClazz
Réponses:
C ++ est orienté objet, en ce sens qu'il prend en charge le paradigme orienté objet pour le développement logiciel.
Cependant, à la différence de Java, C ++ ne vous oblige pas à regrouper les définitions de fonctions dans des classes: la méthode standard C ++ pour déclarer une fonction est de simplement déclarer une fonction, sans aucune classe.
Si à la place vous parlez de déclaration / définition de méthode, la méthode standard consiste à placer uniquement la déclaration dans un fichier include (normalement nommé
.h
ou.hpp
) et la définition dans un fichier d'implémentation séparé (normalement nommé.cpp
ou.cxx
). Je conviens que c'est en effet quelque peu ennuyeux et nécessite une certaine duplication, mais c'est ainsi que le langage a été conçu.Pour des expériences rapides et des projets sur un seul fichier, tout fonctionnerait ... mais pour des projets plus importants, cette séparation est pratiquement nécessaire.
Remarque: même si vous connaissez Java, C ++ est un langage complètement différent ... et c'est un langage qui ne peut pas être appris en expérimentant. La raison en est que c'est un langage assez complexe avec beaucoup d'asymétries et des choix apparemment illogiques, et surtout, lorsque vous faites une erreur, il n'y a pas d '"anges d'erreur d'exécution" pour vous sauver comme en Java ... mais il y en a à la place " démons de comportement indéfinis ".
La seule façon raisonnable d'apprendre le C ++ est de lire ... peu importe à quel point vous êtes intelligent, vous ne pouvez pas deviner ce que le comité a décidé (être intelligent est parfois même un problème parce que la bonne réponse est illogique et est une conséquence patrimoine.)
Choisissez simplement un ou deux bons livres et lisez-les d'un bout à l'autre.
la source
Le premier définit votre fonction membre comme une fonction en ligne , tandis que le second ne le fait pas. La définition de la fonction dans ce cas réside dans l'en-tête lui-même.
La deuxième implémentation placerait la définition de la fonction dans le fichier cpp.
Les deux sont sémantiquement différents et ce n'est pas seulement une question de style.
la source
La définition des fonctions est meilleure en dehors de la classe. De cette façon, votre code peut rester en sécurité si nécessaire. Le fichier d'en-tête doit simplement donner des déclarations.
Supposons que quelqu'un veuille utiliser votre code, vous pouvez simplement lui donner le fichier .h et le fichier .obj (obtenu après compilation) de votre classe. Il n'a pas besoin du fichier .cpp pour utiliser votre code.
De cette façon, votre implémentation n'est visible par personne d'autre.
la source
La méthode «À l'intérieur de la classe» (I) fait la même chose que la méthode «À l'extérieur de la classe» (O).
Cependant, (I) peut être utilisé lorsqu'une classe n'est utilisée que dans un seul fichier (dans un fichier .cpp). (O) est utilisé lorsqu'il se trouve dans un fichier d'en-tête. Les fichiers cpp sont toujours compilés. Les fichiers d'en-tête sont compilés lorsque vous utilisez #include "header.h".
Si vous utilisez (I) dans un fichier d'en-tête, la fonction (Fun1) sera déclarée à chaque fois que vous incluez #include "header.h". Cela peut conduire à déclarer la même fonction plusieurs fois. Ceci est plus difficile à compiler et peut même entraîner des erreurs.
Exemple d'utilisation correcte:
Fichier1: "Clazz.h"
Fichier2: "Clazz.cpp"
File3: "UseClazz.cpp"
File4: "AlsoUseClazz.cpp"
File5: "DoNotUseClazzHeader.cpp"
la source
Les fonctions membres peuvent être définies dans la définition de classe ou séparément à l'aide de l'opérateur de résolution de portée, ::. La définition d'une fonction membre dans la définition de classe déclare la fonction en ligne, même si vous n'utilisez pas le spécificateur en ligne. Donc, soit vous pouvez définir la fonction Volume () comme ci-dessous:
Si vous le souhaitez, vous pouvez définir la même fonction en dehors de la classe en utilisant l'opérateur de résolution de portée, :: comme suit
Ici, le seul point important est que vous devrez utiliser le nom de la classe juste avant :: operator. Une fonction membre sera appelée à l'aide d'un opérateur point (.) Sur un objet où elle manipulera les données liées à cet objet uniquement comme suit:
(à partir de: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm ), les deux méthodes sont légales.
Je ne suis pas un expert, mais je pense que si vous ne mettez qu'une seule définition de classe dans un fichier, cela n'a pas vraiment d'importance.
mais si vous appliquez quelque chose comme la classe interne, ou si vous avez plusieurs définitions de classe, la seconde serait difficile à lire et à maintenir.
la source
Le premier doit être placé dans le fichier d'en-tête (où réside la déclaration de la classe). Le second peut être n'importe où, soit l'en-tête ou, généralement, un fichier source. En pratique, vous pouvez mettre de petites fonctions dans la déclaration de classe (qui les déclare implicitement en ligne, bien que ce soit le compilateur qui décide en fin de compte si elles seront insérées ou non). Cependant, la plupart des fonctions ont une déclaration dans l'en-tête et l'implémentation dans un fichier cpp, comme dans votre deuxième exemple. Et non, je ne vois aucune raison pour laquelle cela serait moins lisible. Sans oublier que vous pouvez en fait diviser l'implémentation d'un type sur plusieurs fichiers cpp.
la source
Une fonction définie dans une classe est par défaut traitée comme une fonction en ligne. Une raison simple pour laquelle vous devez définir votre fonction à l'extérieur:
Un constructeur de la classe vérifie les fonctions virtuelles et initialise un pointeur virtuel pour pointer vers le VTABLE approprié ou la table de méthode virtuelle , appelle le constructeur de la classe de base et initialise les variables de la classe actuelle, de sorte qu'il effectue un certain travail.
Les fonctions en ligne sont utilisées lorsque les fonctions ne sont pas si compliquées et évitent la surcharge de l'appel de fonction. (La surcharge comprend un saut et une branche au niveau matériel.) Et comme décrit ci-dessus, le constructeur n'est pas aussi simple à considérer que celui en ligne.
la source