2014-01-10 80 views
0

問題:我得到關於這兩個運算符的鏈接器錯誤。更具體地說,這裏是確切的錯誤消息:重載輸入/輸出操作符,爲什麼它以這種方式與其他方式相互作用?

注意:如果你讀到底部我提到它,我有'工作解決方案'。我不知道它爲什麼會這樣,而不是這樣。我更喜歡這種方法,因爲它看起來更乾淨,沒有輸入/輸出操作符掛在我的聲明之上。對不起,長度。我修剪了一些不必要的東西,比如我已經存在的其他重載操作符,因爲它們不相關。

poly.obj : error LNK2005: "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Poly &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@@@Z) already defined in lab1.obj 
1>poly.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Poly const &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@@@Z) already defined in lab1.obj 
1>d:\... fatal error LNK1169: one or more multiply defined symbols found 

在我的.h文件(你將在下面看到)我有聲明爲朋友,使他們能夠訪問私有成員都期望運營商。我也有他們作爲非會員功能,這是運營商超載「指南」在這個網站上說是正確的。操作員>>不完整,但與此無關。我有一個想法,這可能與兩個地方我有「#include iostream」這個事實有關,因爲.cpp包含.h,那麼它是否因此而嘔吐?不知道這是否是一個正確的預感。以下是完整的.h文件中:

//file poly.h 

#ifndef POLY_H 
#define POLY_H 

#include <iostream> 
using namespace std; 

class Poly { 

public: 
    Poly(int = 0, int = 0);      //default constructor 
    Poly(const Poly &);       //copy constructor 
    ~Poly();         //destructor 

    friend ostream& operator<<(ostream& output, const Poly& thePoly); 
    friend istream& operator>>(istream& input, Poly& thePoly); 

private: 
    int* polynomial; 
    int maxExponent; 
}; 

istream& operator>>(istream& input, Poly& thePoly) { 

    return input; 
} 

ostream& operator<<(ostream& output, const Poly& thePoly) { 
    bool isZero = true; 

    for (int i = thePoly.maxExponent; i > 0; i--) { 
     if (thePoly.polynomial[i] != 0) { 
      if (thePoly.polynomial[i] < 0) { 
       output << " -"; 
      } 
      else { 
       output << " +"; 
      } 

      output << thePoly.polynomial[i]; 

      if (i != 0) { 
       output << "x"; 
      } 
      if (i != 1) { 
       output << "^"; 
      } 

      output << i; 
      isZero = false; 
     } 
    } 

    if (isZero) { 
     output << " 0"; 
    } 

    return output; 
} 

#endif 

這裏是在鏈接錯誤引用的輔助文件:

// DO NOT change anything in this file. Your code must compile and give the 
// correct output with this main on the linux machines. 

// Make sure the file containing the member function source is: poly.cpp 
// Use all lowercase in the file names. 

// This main does not do a thorough job of testing. When testing arrays, 
// be sure to test the middle and also all the boundary conditions. Test 
// values on the boundary and outside the boundaries, i.e., too big/small. 

#include "poly.h" 
#include <iostream> 
using namespace std; 

int main() { 
    Poly A(5, 7), B(3, 4), C(2), D(A), X, Y; 
    Poly A2, B2, Z1, Z2; 

    // set polynomials A and B to desired values 
    // A = +5x^7 -4x^3 +10x -2 
    // B = +3x^4 +1x^3 
    cout << "Enter terms for polynomial A. Enter a coefficient " << endl 
     << "then exponent for each term. Enter -1 -1 to terminate." << endl; 
    cin >> A;          // or use a bunch of setCoeff 
    cout << "Enter terms for polynomial B. Enter a coefficient " << endl 
     << "then exponent for each term. Enter -1 -1 to terminate." << endl; 
    cin >> B;          // or use a bunch of setCoeff 

    // outputs exactly what is in quotes: "A = +5x^7 -4x^3 +10x -2" 
    cout << "A =" << A << endl; 
    // outputs exactly what is in quotes: "B = +3x^4 +1x^3" 
    cout << "B =" << B << endl << endl; 

    return 0; 
} 

奇怪(當然至少對我來說)是,如果我放棄的聲明並將整個函數移動到公共聲明之上,但仍然在類中,然後程序正確地編譯爲什麼是這個???當然,我還沒有能夠測試這個編譯是否正確意味着它的正常工作,因爲我需要完成操作員>>以便我可以輸入數據然後輸出。

這就是我所說的上述變化:

#ifndef POLY_H 
#define POLY_H 

#include <iostream> 
using namespace std; 

class Poly { 

    friend istream& operator>>(istream& input, Poly& thePoly) { 

     return input; 
    } 

    friend ostream& operator<<(ostream& output, const Poly& thePoly) { 
     bool isZero = true; 

     for (int i = thePoly.maxExponent; i > 0; i--) { 
      if (thePoly.polynomial[i] != 0) { 
       if (thePoly.polynomial[i] < 0) { 
        output << " -"; 
       } 
       else { 
        output << " +"; 
       } 

       output << thePoly.polynomial[i]; 

       if (i != 0) { 
        output << "x"; 
       } 
       if (i != 1) { 
        output << "^"; 
       } 

       output << i; 
       isZero = false; 
      } 
     } 

     if (isZero) { 
      output << " 0"; 
     } 

     return output; 
    } 

public: 
    Poly(int = 0, int = 0);      //default constructor 
    Poly(const Poly &);       //copy constructor 
    ~Poly();         //destructor 

private: 
    int* polynomial; 
    int maxExponent; 
}; 



#endif 
+1

如果你在一個頭文件中寫了一個自由函數體(比如'operator <<'),你必須將它標記爲'inline',否則你違反了ODR,並看到結果(通常是鏈接器錯誤)。 –

+0

@MatteoItalia那麼,這絕對解決了這個問題。介紹ODR代表什麼? –

+1

http://en.m.wikipedia.org/wiki/One_Definition_Rule –

回答

3

(從註釋中移動)

如果你寫了一個免費的函數體(如您的運營商< <)在一個標題你必須標記爲內聯,否則你違反了ODR,你看到的結果(通常是鏈接器錯誤)。

相關問題