Correction des définitions multiples d'une erreur de fonction en C++

Muhammad Husnain 12 octobre 2023
Correction des définitions multiples d'une erreur de fonction en C++

Cet article traite de la solution à l’erreur fréquente en C++, qui est plusieurs définitions d'une fonction.

Correction de l’erreur définitions multiples d'une fonction en C++

Une telle erreur est généralement causée lorsque nous essayons de séparer le prototype de la fonction et sa définition. Par conséquent, il est recommandé de séparer les prototypes et les définitions dans différents fichiers et d’inclure le fichier en conséquence.

Considérez l’exemple ci-dessous pour comprendre le problème.

Exemple de code (file1.cpp):

// file1.cpp
#include <iostream>
using namespace std;

class classB {
  friend void f1();

 public:
  classB(int i = 1, int j = 2) : a(i), b(j) {
    cout << "Hello from constructor\n";
  }

 private:
  int a;
  int b;
  void printfun() { cout << "a=" << a << endl << "b=" << b << endl; }
};
void f1() {  // ERROR HERE
  cout << "f1 start" << endl;
  classB tmp(3, 5);
  tmp.printfun();
  cout << "f1 end" << endl;
}

Exemple de code (main.cpp) :

// main.cpp
#include <iostream>

#include "file1.cpp"
using namespace std;

int main() {
  cout << "calling function" << endl;
  f1();
  cout << "exit from main" << endl;
  return 0;
}

C’est ce qui se passe dans votre situation. A cause de #include dans le fichier file1.cpp, file1.cpp et main.cpp incluent une définition de f1(), et l’éditeur de liens ne sait pas lequel utiliser dans votre programme et s’en plaint.

La solution est de supprimer le fichier CPP contenant la définition de f1() de main.cpp et d’inclure à la place la déclaration de f1() dans un fichier d’en-tête séparé et de l’inclure dans main.cpp. Le compilateur aura la déclaration de f1() à traiter, et l’éditeur de liens n’aura qu’une seule définition de f1() de file1.cpp sur laquelle s’appuyer.

Exemple de code (fichier1.h):

// file1.h
#include <iostream>

class classB {
  friend void f1();

 public:
  classB(int i = 1, int j = 2) : a(i), b(j) {
    std::cout << "Hello from constructor\n";
  }

 private:
  int a;
  int b;
  void printfun() { std::cout << "a=" << a << endl << "b=" << b << std::endl; }
};

Exemple de code (file1.cpp):

// file1.cpp
#include "file1.h"
using namespace std;
void f1() {
  cout << "f1 start" << endl;
  classB tmp(5, 6);
  tmp.printfun();
  cout << "f1 end" << endl;
}

Exemple de code (main.cpp) :

// main.cpp
#include <iostream>

#include "file1.h"
using namespace std;

int main() {
  cout << "calling function" << endl;
  f1();
  cout << "exit from main" << endl;
  return 0;
}

Commençons par le fichier d’en-tête file1.h. Les fichiers d’en-tête contiennent les définitions de tout, comme les définitions de fonction, les définitions de struct ou de classe ou les définitions de constantes.

Cette extension .h indique au compilateur que ce fichier n’est pas à compiler. C’est comme un fichier texte et est lisible par n’importe qui.

Cela implique que le fichier d’en-tête est un fichier de documentation. Si un programmeur souhaite utiliser certaines fonctions à l’avenir, il n’a qu’à vérifier le prototype des fonctions et n’a pas besoin d’entrer dans les détails des définitions de fonctions.

Enfin, le code du modèle doit également figurer dans le fichier d’en-tête.

Le fichier CPP définit maintenant la fonction déclarée dans le fichier d’en-tête. Cela indique au compilateur que ce fichier doit être compilé et converti en un fichier binaire.

L’intégrité de votre code sera protégée et personne d’autre ne pourra le modifier sans votre permission. Cela signifie que cette séparation du code garantit également la sécurité de vos fichiers de code.

Une autre raison derrière cette technique est la portabilité. Par exemple, vous avez écrit un code de recherche binaire qui pourra être utilisé ultérieurement dans de nombreux autres programmes.

Si vous avez ces fichiers séparés pour les fonctions, vous pouvez facilement utiliser ces fonctions dans n’importe quel autre projet.

Enfin, le fichier principal ne contient que la fonction principale et inclut le fichier d’en-tête en haut. Ce fichier ne contient que la fonction main, qui n’appelle que toutes les fonctions et rien d’autre.

Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn

Article connexe - C++ Error