ホームページ > バックエンド開発 > C++ > 関数定義を含むヘッダー ファイルを複数のソース ファイルに含めると、「複数定義」エラーが発生するのはなぜですか?

関数定義を含むヘッダー ファイルを複数のソース ファイルに含めると、「複数定義」エラーが発生するのはなぜですか?

Mary-Kate Olsen
リリース: 2024-11-16 02:07:03
オリジナル
541 人が閲覧しました

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

ヘッダー ファイルの複数定義エラー

問題の定義

次のコード サンプルを考慮してください:

// 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 つの解決策があります。

  1. 演算子を作成<<インライン関数:

    演算子をマークすることで<<インライン関数として使用すると、複数の翻訳単位で定義できます。

    inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
       return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
    ログイン後にコピー
  2. 移動演算子<< complex.cpp への定義:

    または、演算子<<を定義することもできます。 complex.cpp ソース ファイル内の関数。これにより、関数が 1 回だけ定義されるようになります。

追加の解決策

inline キーワードを使用するか、定義をソースに移動する以外にファイルの場合、別の可能な解決策があります:

  1. 関数定義でヘッダー ガードを使用する:

    関数定義の周囲にヘッダー ガードを追加して、複数回定義されないようにします。

    #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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート