Mengapakah memasukkan fail pengepala dengan definisi fungsi dalam berbilang fail sumber membawa kepada ralat \'berbilang definisi\'?

Mary-Kate Olsen
Lepaskan: 2024-11-16 02:07:03
asal
473 orang telah melayarinya

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

Ralat Berbilang Definisi dalam Fail Pengepala

Takrifan Masalah

Pertimbangkan contoh kod berikut:

// 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;
}
Salin selepas log masuk

Apabila menyusun ini kod, pengkompil melaporkan an ralat:

multiple definition of operator<<(std::ostream&, Complex const&)
Salin selepas log masuk

Analisis Ralat

Sebab ralat ini ialah takrifan operator<< fungsi dalam kompleks.h bukan pengisytiharan tetapi definisi sebenar. Ini bermakna apabila kedua-dua complex.cpp dan main.cpp menyertakan fail pengepala, pengkompil cuba untuk menentukan fungsi dua kali. Ini membawa kepada ralat takrifan berbilang.

Pengkompil tidak mengadu tentang fungsi ahli awam real() kerana ia secara tersirat sebaris. Ini bermakna pengkompil menjana kod untuk real() dalam setiap unit terjemahan yang menggunakannya.

Penyelesaian

Terdapat dua penyelesaian utama untuk isu ini:

  1. Buat operator<< Fungsi Sebaris:

    Dengan menandakan operator<< berfungsi sebagai sebaris, ia boleh ditakrifkan dalam berbilang unit terjemahan.

    inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
       return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
    Salin selepas log masuk
  2. Pengendali alih<< Takrif kepada kompleks.cpp:

    Sebagai alternatif, anda boleh mentakrifkan operator<< berfungsi dalam fail sumber complex.cpp, yang memastikan bahawa ia ditakrifkan sekali sahaja.

Penyelesaian Tambahan

Selain menggunakan kata kunci sebaris atau mengalihkan definisi ke sumber fail, terdapat satu lagi penyelesaian yang mungkin:

  1. Gunakan Pengawal Pengepala dalam Fungsi Definisi:

    Anda boleh menambah pengadang pengepala di sekeliling definisi fungsi untuk mengelakkannya daripada ditakrifkan lebih daripada sekali.

    #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
    Salin selepas log masuk

Atas ialah kandungan terperinci Mengapakah memasukkan fail pengepala dengan definisi fungsi dalam berbilang fail sumber membawa kepada ralat \'berbilang definisi\'?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan