Maison > développement back-end > C++ > le corps du texte

Pourquoi l'inclusion d'un fichier d'en-tête avec une définition de fonction dans plusieurs fichiers sources entraîne-t-elle une erreur « définitions multiples » ?

Mary-Kate Olsen
Libérer: 2024-11-16 02:07:03
original
473 Les gens l'ont consulté

Why does including a header file with a function definition in multiple source files lead to a

Erreur de définition multiple dans le fichier d'en-tête

Définition du problème

Considérez l'exemple de code suivant :

// complex.h
#include <iostream>

class Complex {
public:
   Complex(float Real, float Imaginary);

   float real() const { return m_Real; };

private:
   friend std::ostream& operator<<(std::ostream& o, const Complex& Cplx);

   float m_Real;
   float m_Imaginary;
};

std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
   return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}

// complex.cpp
#include "complex.h"

Complex::Complex(float Real, float Imaginary) {
   m_Real = Real;
   m_Imaginary = Imaginary;
}

// main.cpp
#include "complex.h"
#include <iostream>

int main()
{
   Complex Foo(3.4, 4.5);
   std::cout << Foo << "\n";
   return 0;
}
Copier après la connexion

Lors de la compilation de ceci code, le compilateur signale une erreur :

multiple definition of operator<<(std::ostream&, Complex const&)
Copier après la connexion

Analyse des erreurs

La raison de cette erreur est que la définition de l'opérateur<< la fonction dans complex.h n'est pas une déclaration mais une définition réelle. Cela signifie que lorsque complex.cpp et main.cpp incluent le fichier d'en-tête, le compilateur tente de définir la fonction deux fois. Cela conduit à une erreur de définition multiple.

Le compilateur ne se plaint pas de la fonction membre publique real() car elle est implicitement intégrée. Cela signifie que le compilateur génère le code pour real() dans chaque unité de traduction qui l'utilise.

Solutions

Il existe deux solutions principales à ce problème :

  1. Faire de l'opérateur<< une fonction en ligne :

    En marquant l'opérateur<< fonctionne comme en ligne, il peut être défini dans plusieurs unités de traduction.

    inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
       return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
    Copier après la connexion
  2. Opérateur de déplacement<< Définition de complex.cpp :

    Vous pouvez également définir l'opérateur<< fonction dans le fichier source complex.cpp, ce qui garantit qu'il n'est défini qu'une seule fois.

Solution supplémentaire

En plus d'utiliser le mot-clé en ligne ou de déplacer la définition vers une source fichier, il existe une autre solution possible :

  1. Utiliser des protections d'en-tête dans les définitions de fonctions :

    Vous pouvez ajouter des protections d'en-tête autour de la définition de fonction pour éviter qu'il soit défini plus d'une fois.

    #ifndef OPERATOR_LT_LT_DEFINED
    #define OPERATOR_LT_LT_DEFINED
    
    std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
       return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
    
    #endif // OPERATOR_LT_LT_DEFINED
    Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal