I can't for the life of me figure out why I am getting these errors, especially since I have include guards.
These are my errors (please ignore what I named my computer):
1>main.obj : error LNK2005: "class std::basic_ostream > >& __cdecl operator<<(class 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 operator<<(class std::basic_ostream > &,class >Loan &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVLoan@@@Z) already >defined in loan.obj
1>C:\Users\SweetAssSarah\Documents\Visual Studio >2012\Projects\ConsoleApplication4\Debug\a1.exe : fatal error LNK1169: one or more multiply >defined symbols found
And here are my 4 files: 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
Please help!
As already stated in the comments, the << operator needs to be inlined or defined in the cpp file. When you define the function in the header file, it will be compiled in each cpp file where you include the header. If you include the header in more than one cpp file then you get the compiler errors because the same code will be compiled into multiple .obj files. The linker does not know which .obj file to use and throws an error.
Solution 1 - Splitting into .h and .cpp
loan.h
ostream & operator<<(ostream & ostr, Loan & aLoan);
loan.cpp
ostream & operator<<(ostream & ostr, Loan & aLoan) {
aLoan.printOn(ostr);
return ostr;
}
Solution 2 - Inlining
loan.h
inline ostream & operator<<(ostream & ostr, Loan & aLoan) {
aLoan.printOn(ostr);
return ostr;
}
The second solution will cause the compiler to resolve the function call by inlining the function code at every position in the code where an invocation happens. This causes redundancies in the compiled code and should be avoided for large functions.
Solution 3 - Static
loan.h
static ostream & operator<<(ostream & ostr, Loan & aLoan) {
aLoan.printOn(ostr);
return ostr;
}
By declaring the function as static, it has internal linkage. You are still leaving the decision of whether the compiler will inline it or not to the compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With