web-dev-qa-db-fra.com

Séparer le code de classe en un en-tête et un fichier cpp

Je ne comprends pas comment séparer le code d'implémentation et de déclaration d'une classe simple en un nouvel en-tête et un nouveau fichier cpp. Par exemple, comment pourrais-je séparer le code pour la classe suivante?

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y)
  {
    gx = x;
    gy = y;
  }

  int getSum()
  {
    return gx + gy;
  }
};
145
drdrdr

La déclaration de classe va dans le fichier d'en-tête. Il est important que vous ajoutiez les gardes d'inclusion #ifndef ou, si vous êtes sur une plate-forme MS, vous pouvez également utiliser #pragma once. Aussi, j'ai omis le privé, par défaut les membres de la classe C++ sont privés.

// A2DD.h
#ifndef A2DD_H
#define A2DD_H

class A2DD
{
  int gx;
  int gy;

public:
  A2DD(int x,int y);
  int getSum();

};

#endif

et l'implémentation va dans le fichier CPP:

// A2DD.cpp
#include "A2DD.h"

A2DD::A2DD(int x,int y)
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}
205
Ferenc Deak

En général, votre .h contient la définition de classe, qui contient toutes vos données et toutes vos déclarations de méthodes. Comme ça dans ton cas:

A2DD.h:

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y);    
  int getSum();
};

Et puis votre .cpp contient les implémentations des méthodes comme ceci:

A2DD.cpp:

A2DD::A2DD(int x,int y)
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}
15
Nick

Fondamentalement, une syntaxe modifiée de déclaration de fonction/définitions:

a2dd.h

class A2DD
{
private:
  int gx;
  int gy;

public:
  A2DD(int x,int y);

  int getSum();
};

a2dd.cpp

A2DD::A2DD(int x,int y)
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}
5
Corbin

Il est important de signaler aux lecteurs qui tombent sur cette question lors de la recherche du sujet d'une manière plus large que la procédure de réponse acceptée n'est pas requise dans le cas où vous souhaitez simplement scinder votre projet en fichiers. Ce n'est nécessaire que lorsque vous avez besoin de plusieurs implémentations de classes uniques. Si votre implémentation par classe est une, un seul fichier d'en-tête suffit.

Par conséquent, à partir de l'exemple de la réponse acceptée, seule cette partie est nécessaire:

#ifndef MYHEADER_H
#define MYHEADER_H

//Class goes here, full declaration AND implementation

#endif

Les définitions du préprocesseur #ifndef etc. lui permettent d'être utilisé plusieurs fois.

PS Le sujet devient plus clair une fois que vous réalisez que C/C++ est "idiot" et que #include est simplement un moyen de dire "vider ce texte à cet endroit".

4
j riv

A2DD.h

class A2DD
{
  private:
  int gx;
  int gy;

  public:
  A2DD(int x,int y);

  int getSum();
};

A2DD.cpp

  A2DD::A2DD(int x,int y)
  {
    gx = x;
    gy = y;
  }

  int A2DD::getSum()
  {
    return gx + gy;
  }

L'idée est de conserver toutes les signatures de fonction et tous les membres dans le fichier d'en-tête.
Cela permettra aux autres fichiers de projet de voir à quoi ressemble la classe sans avoir à connaître l'implémentation.

Et à part cela, vous pouvez ensuite inclure d'autres fichiers d'en-tête dans l'implémentation à la place de l'en-tête. Ceci est important car les en-têtes inclus dans votre fichier d’en-tête seront inclus (hérités) dans tout autre fichier incluant votre fichier d’en-tête.

4
Yochai Timmer

Vous laissez les déclarations dans le fichier d'en-tête:

class A2DD
{
  private:
  int gx;
  int gy;

  public:
    A2DD(int x,int y); // leave the declarations here
    int getSum();
};

Et mettez les définitions dans le fichier d'implémentation.

A2DD::A2DD(int x,int y) // prefix the definitions with the class name
{
  gx = x;
  gy = y;
}

int A2DD::getSum()
{
  return gx + gy;
}

Vous pouvez mélanger les deux (laissez la définition getSum() dans l'en-tête, par exemple). C'est utile car cela donne au compilateur une meilleure chance d'inline par exemple. Mais cela signifie également que changer l’implémentation (si elle est laissée dans l’en-tête) peut déclencher une reconstruction de tous les autres fichiers incluant l’en-tête.

Notez que pour les modèles, vous devez tout garder dans les en-têtes.

3
Mat

Habituellement, vous ne mettez que des déclarations et des fonctions inline très courtes dans le fichier d'en-tête:

Par exemple:

class A {
 public:
  A(); // only declaration in the .h unless only a short initialization list is used.

  inline int GetA() const {
    return a_;
  }

  void DoSomethingCoplex(); // only declaration
  private:
   int a_;
 };
1
Ivaylo Strandjev