Déclaration de fonction à l'intérieur ou à l'extérieur de la classe

je suis un développeur JAVA qui essaie d'apprendre le C++, mais je ne sais pas vraiment quelle est la meilleure pratique pour les déclarations de fonction 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...

67
demandé sur Blubber 2012-01-31 11:30:20

7 réponses

C++ est orienté objet, en ce sens qu'il soutient le paradigme orienté objet pour le développement de logiciels.

cependant, contrairement à Java, C++ ne vous oblige pas à grouper les définitions de fonctions dans les classes: la manière standard C++ de déclarer une fonction est simplement de déclarer une fonction, sans classe.

si au lieu de cela vous parlez de déclaration de méthode / définition, alors la manière standard est de mettre juste la déclaration dans une include 151920920 " ou .cxx ) et la définition dans un fichier de mise en œuvre distinct (habituellement appelé .cpp ou .cxx ). Je suis d'accord que c'est en effet quelque peu ennuyeux et nécessite une certaine duplication, mais c'est la façon dont le langage a été conçu.

pour des expériences rapides et des projets en file indienne, tout fonctionnerait... mais pour les projets plus importants, cette séparation est pratiquement requise.

Note: même si vous savez Java, C++ est un langage complètement différent... et c'est une langue qui ne peut pas être apprise en expérimentant. La raison en est que c'est un langage assez complexe avec beaucoup d'asymétries et de choix apparemment illogiques, et surtout, quand vous faites une erreur, il n'y a pas d ' "runtime error angels" pour vous sauver comme en Java... mais il y a à la place des "démons de comportement non définis".

la seule façon raisonnable d'apprendre le c++ est de lire... peu importe comment vous êtes intelligents, il est impossible de deviner ce que le Comité a décidé. (En fait, être intelligent est parfois même un problème parce que la bonne réponse est illogique et une conséquence du patrimoine historique.)

il suffit de choisir un bon livre ou deux et de les lire couverture à couverture.

42
répondu 6502 2017-05-23 12:26:10

la première définit votre fonction de membre comme une fonction en ligne , tandis que la seconde 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 mise en oeuvre placerait la définition de la fonction dans le fichier du RPC.

les deux sont sémantiquement différents et ce n'est pas seulement une question de style.

15
répondu Alok Save 2018-07-08 19:39:53

la définition de la fonction est préférable à l'extérieur de la classe. De cette façon, votre code peut rester en sécurité si nécessaire. Le fichier d'en-tête devrait simplement donner des déclarations.

si quelqu'un veut utiliser votre code, vous pouvez lui donner .h fichier et le .fichier obj (obtenu après compilation) de votre classe. Il n'a pas besoin de la .fichier cpp pour l'utilisation de votre code.

de cette façon, votre implémentation n'est visible à personne d'autre.

12
répondu Ajit Vaze 2012-01-31 11:47:15

La "à l'Intérieur de la classe" (I) méthode fait la même chose que le "en dehors de la classe" (O) de la méthode.

Toutefois, (I) peut être utilisé lorsqu'une classe est utilisé uniquement dans un seul fichier (à l'intérieur d'un .fichier cpp). (O) est utilisé lorsqu'il est dans un fichier d'en-tête. les fichiers du RPC sont toujours compilés. 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 l'en-tête #include".h." Cela peut conduisez à déclarer la même fonction plusieurs fois. Cela est plus difficile à compiler, et peut même conduire à des erreurs.

exemple d'usage correct:

Fichier1: "Clazz.h"

//This file sets up the class with a prototype body. 

class Clazz
{
public:
    void Fun1();//This is a Fun1 Prototype. 
};

Fichier2: "Clazz.rpc"

#include "Clazz.h" 
//this file gives Fun1() (prototyped in the header) a body once.

void Clazz::Fun1()
{
    //Do stuff...
}

File3: "UseClazz.rpc"

#include "Clazz.h" 
//This file uses Fun1() but does not care where Fun1 was given a body. 

class MyClazz;
MyClazz.Fun1();//This does Fun1, as prototyped in the header.

File4: "AlsoUseClazz.rpc"

#include "Clazz.h" 
//This file uses Fun1() but does not care where Fun1 was given a body. 

class MyClazz2;
MyClazz2.Fun1();//This does Fun1, as prototyped in the header. 

File5: "DoNotUseClazzHeader.rpc"

//here we do not include Clazz.h. So this is another scope. 
class Clazz
{
public:
    void Fun1()
    {
         //Do something else...
    }
};

class MyClazz; //this is a totally different thing. 
MyClazz.Fun1(); //this does something else. 
10
répondu user2877673 2013-10-14 05:09:44

les fonctions de membre peuvent être définies dans la définition de classe ou séparément en utilisant l'opérateur de résolution de portée, ::. Définir une fonction membre dans la définition de classe déclare la fonction inline, même si vous n'utilisez pas le spécificateur inline. Ainsi, soit vous pouvez définir la fonction Volume () comme suit:

class Box
{
  public:

     double length;
     double breadth;    
     double height;     

     double getVolume(void)
     {
        return length * breadth * height;
     }
};

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 scope, comme suit:

double Box::getVolume(void)
{
   return length * breadth * height;
}

Ici, le seul point important est que vous devez utiliser le nom de la classe juste avant:: operator. Une fonction membre sera appelée en utilisant un opérateur de point (.) sur un objet où il manipule des données relatives à cet objet uniquement comme suit:

Box myBox;           

myBox.getVolume();  

(de: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm ) , les deux façons sont légales.

Je ne suis pas un expert, mais je pense, si vous mettez une seule classe définition dans un fichier, alors il n'a pas vraiment d'importance.

mais si vous appliquez quelque chose comme la classe intérieure, ou si vous avez la définition de classe multiple, la seconde serait difficile à lire et à maintenir.

3
répondu user116541 2015-06-25 04:18:24

La première doit être mis dans le fichier d'en-tête (où la déclaration de la classe réside). Le second peut être n'importe où, soit l'en-tête, soit 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 inlined 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 second exemple. Et non, je ne vois pas pourquoi ce serait moins lisible. Sans compter que vous pourriez réellement diviser la mise en œuvre pour un type parmi plusieurs dossiers du RPC.

2
répondu Marius Bancila 2012-01-31 07:35:05

une fonction définie à l'intérieur d'une classe est par défaut traitée comme une fonction en ligne. Une raison simple pour 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 la table VTABLE appropriée ou la table de méthode virtuelle , appelle le constructeur de la classe de base, et initialise les variables de la classe actuelle, donc il fait réellement un certain travail.

les fonctions en ligne sont utilisées lorsque les fonctions ne sont pas si compliquées et évitent les frais généraux de l'appel de fonction. (Les frais généraux comprennent un saut et une branche au niveau du matériel.) Et comme décrit ci-dessus, le constructeur n'est pas aussi simple à considérer que inline.

1
répondu R Mehta 2016-11-05 03:12:14