Maison >développement back-end >C++ >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 » ?
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; }
Lors de la compilation de ceci code, le compilateur signale une erreur :
multiple definition of operator<<(std::ostream&, Complex const&)
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.
Il existe deux solutions principales à ce problème :
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; }
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.
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 :
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
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!