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; }
Apabila menyusun ini kod, pengkompil melaporkan an ralat:
multiple definition of operator<<(std::ostream&, Complex const&)
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.
Terdapat dua penyelesaian utama untuk isu ini:
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; }
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.
Selain menggunakan kata kunci sebaris atau mengalihkan definisi ke sumber fail, terdapat satu lagi penyelesaian yang mungkin:
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
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!