Heim >Backend-Entwicklung >C++ >Warum führt das Einfügen einer Header-Datei mit einer Funktionsdefinition in mehrere Quelldateien zu einem „Mehrfachdefinition'-Fehler?

Warum führt das Einfügen einer Header-Datei mit einer Funktionsdefinition in mehrere Quelldateien zu einem „Mehrfachdefinition'-Fehler?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-16 02:07:03553Durchsuche

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

Mehrfachdefinitionsfehler in der Header-Datei

Problemdefinition

Berücksichtigen Sie das folgende Codebeispiel:

// 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;
}

Beim Kompilieren Code meldet der Compiler einen Fehler:

multiple definition of operator<<(std::ostream&, Complex const&)

Fehleranalyse

Der Grund für diesen Fehler ist, dass die Definition des Operators<< Die Funktion in complex.h ist keine Deklaration, sondern eine tatsächliche Definition. Das bedeutet, dass der Compiler versucht, die Funktion zweimal zu definieren, wenn sowohl complex.cpp als auch main.cpp die Header-Datei enthalten. Dies führt zum Mehrfachdefinitionsfehler.

Der Compiler beschwert sich nicht über die öffentliche Memberfunktion real(), da sie implizit inline ist. Das bedeutet, dass der Compiler den Code für real() in jeder Übersetzungseinheit generiert, die ihn verwendet.

Lösungen

Es gibt zwei Hauptlösungen für dieses Problem:

  1. Machen Sie den Operator<< eine Inline-Funktion:

    Durch Markieren des Operators<< Als Inline-Funktion kann es in mehreren Übersetzungseinheiten definiert werden.

    inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
       return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
  2. Verschiebeoperator<< Definition zu complex.cpp:

    Alternativ können Sie den Operator << Funktion in der Quelldatei complex.cpp, die sicherstellt, dass sie nur einmal definiert wird.

Zusätzliche Lösung

Neben der Verwendung des Inline-Schlüsselworts oder dem Verschieben der Definition in eine Quelle Datei, gibt es eine andere mögliche Lösung:

  1. Verwenden Sie Header-Schutz in Funktionsdefinitionen:

    Sie können Header-Schutz um die Funktionsdefinition herum hinzufügen, um dies zu verhindern es verhindert, dass es mehr als einmal definiert wird.

    #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

Das obige ist der detaillierte Inhalt vonWarum führt das Einfügen einer Header-Datei mit einer Funktionsdefinition in mehrere Quelldateien zu einem „Mehrfachdefinition'-Fehler?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn