次のコード サンプルを考慮してください:
// 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; }
これをコンパイルするとき
multiple definition of operator<<(std::ostream&, Complex const&)
このエラーの理由は、演算子<<の定義が間違っていることです。 complex.h の関数は宣言ではなく、実際の定義です。これは、complex.cpp と main.cpp の両方にヘッダー ファイルがインクルードされている場合、コンパイラは関数の定義を 2 回試行することを意味します。これにより、複数定義エラーが発生します。
パブリック メンバー関数 real() は暗黙的にインライン展開されるため、コンパイラはこの関数についてエラーを出しません。これは、コンパイラが real() を使用するすべての翻訳単位で real() のコードを生成することを意味します。
この問題には、主に 2 つの解決策があります。
演算子を作成<<インライン関数:
演算子をマークすることで<<インライン関数として使用すると、複数の翻訳単位で定義できます。
inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) { return o << Cplx.m_Real << " i" << Cplx.m_Imaginary; }
移動演算子<< complex.cpp への定義:
または、演算子<<を定義することもできます。 complex.cpp ソース ファイル内の関数。これにより、関数が 1 回だけ定義されるようになります。
inline キーワードを使用するか、定義をソースに移動する以外にファイルの場合、別の可能な解決策があります:
関数定義でヘッダー ガードを使用する:
関数定義の周囲にヘッダー ガードを追加して、複数回定義されないようにします。
#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
以上が関数定義を含むヘッダー ファイルを複数のソース ファイルに含めると、「複数定義」エラーが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。