首頁 > 後端開發 > C++ > 為什麼在多個來源檔案中包含帶有函數定義的頭檔會導致'多重定義”錯誤?

為什麼在多個來源檔案中包含帶有函數定義的頭檔會導致'多重定義”錯誤?

Mary-Kate Olsen
發布: 2024-11-16 02:07:03
原創
544 人瀏覽過

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&)
登入後複製

錯誤分析

這個錯誤的原因是運算子的定義

編譯器不會抱怨公用成員函數 real(),因為它是隱含的內聯。這意味著編譯器會在每個使用 real() 的翻譯單元中產生 real() 的程式碼。

此問題有兩個主要解:

  1. 製作運算子

    透過標記運算子

    inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
       return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
    登入後複製
  2. 行動運算子

    或者,您可以定義運算子

其他解決方案

除了使用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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板