2013-10-02 83 views
4

我不能爲我的生活弄清楚爲什麼我會得到這些錯誤,特別是因爲我已經包括警衛。已經定義Obj?鏈接錯誤?

這是我的錯誤(請忽略我叫我的電腦):

1> main.obj:錯誤LNK2005:「類的std :: basic_ostream>> & __cdecl操作< <(類STD: :basic_ostream> &,class> Date &)「(?? 6 @ YAAAV?$ basic_ostream @ DU?$ char_traits @ D @ std @@@ std @@ AAV01 @ AAVDate @@@ Z)already> defined in loan.obj

1> main.obj:error LNK2005:「class std :: basic_ostream」> & __cdecl運算符< <(class std :: basic_ostream> &,class> Loan &)「(?? 6 @ YAAAV?$ basic_ostream @ DU?$ char_traits @ D @ std @@@ std @@ AAV01 @ AAVLoan @@@ Z)already>在loan.obj定義

1> C:\用戶\ SweetAssSarah \文件\的Visual Studio> 2012 \項目\ ConsoleApplication4 \調試\ a1.exe:致命錯誤LNK1169:一個或一個以上乘法>定義的符號發現

這裏是我的4個文件: Main.cpp的:

#ifndef _main_cpp 
#define _main_cpp 

#include<iostream> 
#include "loan.h" 
#include "date.h" 

using namespace std; 

void main(){ 
    const int MAX_SIZE = 80; 
    char response[MAX_SIZE]; 

    Loan sarah("Sarah", "123 Awesomeville ", Date (01,February,2010)); 

    cout << sarah.getName() << " address: " << sarah.getAddress() << endl; 
    cout << "Date: " << sarah.getDate() << endl; 

    //keep console open until user types a key and enter 
    cout <<"\n\n" << "Press ENTER to continue"; 
    cin.getline(response, MAX_SIZE); 

    return; 
}  
#endif 

loan.cpp:

#ifndef _loan_cpp 
#define _loan_cpp 

#include <iostream> 
#include "loan.h" 
#include "date.h" 

using namespace std; 

Loan::Loan(char * aName, char * anAddress, Date aDate){ 
    name = aName; 
    address = anAddress; 
    date = aDate; 
    cout <<"CONSTRUCTING: " << name << "\n"; 
}  
Loan::~Loan(){ 
    cout << "DESTRUCTING: " << name << endl; 
} 
char * Loan::getName() {return name;} 
char * Loan::getAddress(){return address;} 
Date Loan::getDate(){return date;} 

void Loan:: printOn(ostream & ostr) { 
    cout << name << " address: " << address << endl; 
}  
#endif 

loan.h:

#ifndef _loan_h 
#define _loan_h 

#include <math.h> //for the pow() function to do exponentiation 
#include <iostream> 
#include "date.h" 

using namespace std; 

class Loan{ 
public: 
    Loan(char *, char *, Date);//constructor 
    ~Loan(); 

    char * getName(); 
    char * getAddress(); 
    Date getDate(); 

    void printOn(ostream & ostr); 
private: 
    char * name; 
    char * address; 
    Date date; //requires class Date to have a default constructor 

}; 
ostream & operator<<(ostream & ostr, Loan & aLoan) { 
    aLoan.printOn(ostr); 
    return ostr; 
} 
#endif 

date.h:

#ifndef _date_h 
#define _date_h 
#include <iostream> 

enum Month {January=1, February, March, April, May, June, July, August, 
September, October, November, December}; 

using namespace std; 

class Date{ 
public: 
// Date() {}; 
    Date(int aDay = 1, Month aMonth = May, int aYear = 2005){ 
     day = aDay; 
     month = aMonth; 
     year = aYear; 
}  
void printOn(ostream & o){ 
    o << day << "/" << month << "/" << year; 
} 
private: 
    int day; 
    Month month; 
    int year; 
};  
ostream & operator<<(ostream & ostr, Date & d) { 
    d.printOn(ostr); 
    return ostr; 
} 
#endif 

請幫幫忙!

+2

只需將* inline *放在運算符<<()定義的前面,以便多個定義不會產生該錯誤。 –

+1

我從來沒有聽說過內聯 - 非常感謝你介紹我! – Sarah

+0

'inline'爲我工作(在'cpp'中)。仍在考慮爲什麼。 –

回答

12

正如評論中所述,< <運算符需要在cpp文件中內聯或定義。在頭文件中定義函數時,它將被編譯到包含頭文件的每個cpp文件中。如果你在多個cpp文件中包含頭文件,那麼你會得到編譯器錯誤,因爲相同的代碼會被編譯成多個.obj文件。鏈接器不知道要使用哪個.obj文件並引發錯誤。

溶液1 - 分裂成的.h和.cpp

loan.h

ostream & operator<<(ostream & ostr, Loan & aLoan); 

loan.cpp

ostream & operator<<(ostream & ostr, Loan & aLoan) { 
    aLoan.printOn(ostr); 
    return ostr; 
} 

解決方案2 - 內聯

升oan.h

inline ostream & operator<<(ostream & ostr, Loan & aLoan) { 
    aLoan.printOn(ostr); 
    return ostr; 
} 

第二種解決方案將導致編譯器通過在在一個調用發生的代碼的每個位置內聯函數代碼來解決函數調用。這會導致編譯代碼中的冗餘,並且應該避免大型函數。

解決方案3 - 靜態

loan.h

static ostream & operator<<(ostream & ostr, Loan & aLoan) { 
    aLoan.printOn(ostr); 
    return ostr; 
} 

通過聲明該功能的靜態的,它具有內部連接。您仍然決定編譯器是否將它內聯到編譯器。

相關問題