Thread: LNK2005 error (multiple declarations?)

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    29

    LNK2005 error (multiple declarations?)

    Hi all!

    I have a class that is distributed between its definition (popClass.h) and its implementation (popClass.cpp). However, when I go to compile this collection, I get a LNK2005 error (all errors at bottom of this message) for almost every function... I've double checked to make sure I didn't declare things twice, and it doesn't appear to me that I did.

    Can anyone help figure out why I'm getting this error?

    Thanks!!

    popClass.h
    Code:
    #ifndef __POPCLASS_HEADER
    #define __POPCLASS_HEADER
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    class popClass
    {
    	friend ostream& operator << (ostream& streamobj, const popClass& inpopClass); //Overloaded extraction operator. Preconditon: none. Postcondition: outputs popName;
    
    private:
    	string popName;				//Soda Pop Name
    	float basePrice;			//Base price of the soda
    	vector<int> casesSold;		//Number of cases sold, each element of the vector is a new sale and corresponds to the same element of soldPrice vector
    	vector<float> soldPrice;	//Price for each sale. Each element corresponds to the same element of casesSold vector.
    public:
    	popClass();									//Default constructor. Precondition: none. Postcondition: sets popName = ""; basePrice = 0.0; casesSold and soldPrice uninitalized
    	popClass(const string inName, const float inPrice);		//Constructor. Precondition: inName not empty. Postcondition: popName = inName; basePrice = inPrice; casesSold and soldPrice uninitalized
    	float profitMargin() const;					//Computes the profit margin of the pop. Precondition: none. Postcondition: returns the profit margin per case.
    	float totalProfit() const;					//Computes the total profit (total sales - total cost). Precondition: none. Postcondition: returns the total profit
    	float operator+(const popClass& inpopClass) const;		//Adds the base prices of two pops together. Precondition: none. Postcondition: returns basePrice of the two objects added together
    	string getName() const;							//Gets the name of the pop. Precondition: None. Postcondition: returns popName;
    	void addSale(const int numCasesSold, const float salePrice); //Adds a sale to the class. Precondition: numCasesSold >= 0. Postcondition: places numCasesSold at end of casesSold vector; places salePrice at end of soldPrice vector. If precondition not met, outputs this to the user.
    };
    
    #endif


    popClass.cpp
    Code:
    #ifndef __POPCLASS__IMPLEMENTATION
    #define __POPCLASS__IMPLEMENTATION
    #include <iostream>
    #include <string>
    #include <vector>
    #include "popClass.h"
    
    using namespace std;
    
    //Overloaded extraction operator. Preconditon: none. Postcondition: outputs popName;
    ostream& operator << (ostream& streamobj, const popClass& inpopClass) 
    {
    	streamobj << inpopClass.popName;
    	return streamobj;
    }
    
    //Default constructor. Precondition: none. Postcondition: sets popName = ""; basePrice = 0.0; casesSold and soldPrice uninitalized
    popClass::popClass()
    {
    	popName = "";
    	basePrice = 0.0f;
    }
    
    //Constructor. Precondition: inName not empty. Postcondition: popName = inName; basePrice = inPrice; casesSold and soldPrice uninitalized
    popClass::popClass(const string inName, const float inPrice)		
    {
    	popName = inName;
    	basePrice = inPrice;
    }
    
    //Computes the profit margin of the pop. Precondition: none. Postcondition: returns the profit margin per case.
    float popClass::profitMargin() const
    {
    	/**********
    	Iterate simultaneously through casesSold and soldPrice. Subtract basePrice from soldPrice
    	and multiply the result by casesSold. Add all iterations together, and divide by the total number
    	of all cases sold. Return this value, stored in	profit.
    	***********/
    	float profit = 0.0f;		//profit margin to be returned
    	int totalcases = 0;			//number of total cases sold
    	float marginPerSale = 0.0f;	//profit margin per sale 
    	//Iterate through all sale data
    	for (int a=0; a < (int)casesSold.size(); a++)
    	{
    		marginPerSale = soldPrice[a] - basePrice;
    		profit += marginPerSale * casesSold[a];
    		totalcases += casesSold[a];
    	}
    	//compute margin
    	profit = (profit / totalcases);
    	return profit;
    }
    
    //Computes the total profit (total sales - total cost). Precondition: none. Postcondition: returns the total profit
    float popClass::totalProfit() const
    {				
    	/********
    	Iterate simultaneously through casesSold and soldPrice. Subtract basePrice from soldPrice
    	and multiply by the number of casesSold. Add all of these together and return the value.
    	*********/
    	float profit = 0.0;			//total profit to be returned
    	for (int a=0; a < (int)casesSold.size(); a++)
    	{
    		profit += (soldPrice[a] - basePrice) * casesSold[a];
    	}
    	return profit;
    }
    //Adds the base prices of two pops together. Precondition: none. Postcondition: returns basePrice of the two objects added together
    float popClass::operator+ (const popClass& inpopClass) const
    {
    	return (basePrice + inpopClass.basePrice);
    }
    	
    //Gets the name of the pop. Precondition: None. Postcondition: returns popName;
    string popClass::getName() const
    {
    	return popName;
    }
    
    //Adds a sale to the class. Precondition: numCasesSold >= 0. Postcondition: places numCasesSold at end of casesSold vector; places salePrice at end of soldPrice vector. If precondition not met, outputs this to the user.
    
    void popClass::addSale(int numCasesSold, float salePrice)
    {
    	//test precondition
    	if (numCasesSold < 0)
    	{
    		cout << "Number of cases sold for " << popName << " at price " << salePrice << " is less than zero. This sale will not be recorded." << endl;
    	}
    	else
    	{
    		casesSold.push_back(numCasesSold);
    		soldPrice.push_back(salePrice);
    	}
    }
    
    #endif
    popTest.cpp
    Code:
    #include <iostream>
    #include "popClass.cpp"
    
    using namespace std;
    
    int main()
    {
    	popClass myPop;
    	return 0;
    }

    Errors:

    Code:
    Error	1	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 popClass const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVpopClass@@@Z) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	2	error LNK2005: "public: __thiscall popClass::popClass(void)" (??0popClass@@QAE@XZ) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	3	error LNK2005: "public: __thiscall popClass::popClass(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float)" (??0popClass@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@Z) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	4	error LNK2005: "public: float __thiscall popClass::profitMargin(void)const " (?profitMargin@popClass@@QBEMXZ) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	5	error LNK2005: "public: float __thiscall popClass::totalProfit(void)const " (?totalProfit@popClass@@QBEMXZ) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	6	error LNK2005: "public: float __thiscall popClass::operator+(class popClass const &)const " (??HpopClass@@QBEMABV0@@Z) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	7	error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall popClass::getName(void)const " (?getName@popClass@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	8	error LNK2005: "public: void __thiscall popClass::addSale(int,float)" (?addSale@popClass@@QAEXHM@Z) already defined in popClass.obj	testSodaPop.obj	PopProject
    Error	9	fatal error LNK1169: one or more multiply defined symbols found	C:\Documents and Settings\Sean\My Documents\Visual Studio 2008\Projects\UNL\CSE156\PopProject\Debug\PopProject.exe	PopProject

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    popTest.cpp

    Code:
    #include <iostream>
    #include "popClass.cpp"
    That's not right.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You don't put include guards around "cpp" files, because you don't include them. You only include headers.

    Each cpp file is compiled separately (as one compilation unit), and if one cpp file includes another, the result is that the contents of that file get compiled twice (include guards only have a meaning within a compilation unit) and the symbols will be defined twice.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Sep 2009
    Posts
    29
    Thanks for the tips!

    It's always the simple things in life, eh?

    I had tried the include guards as a last-ditch effort. Thanks for the explanation It's amazing what changing .cpp to .h in an include statement will do

    Thanks again guys!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. The so annoying LNK2005... please help!
    By Mikey_S in forum C++ Programming
    Replies: 14
    Last Post: 02-01-2009, 04:22 AM
  2. Linking problems in Visual Studio
    By h3ro in forum C++ Programming
    Replies: 5
    Last Post: 03-04-2008, 02:39 PM
  3. VC++ a POS
    By Welder in forum Windows Programming
    Replies: 40
    Last Post: 11-07-2007, 03:07 PM
  4. Variables already defined while linking.
    By xconspirisist in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2005, 05:20 AM
  5. DLL compiling question
    By Noose in forum Windows Programming
    Replies: 2
    Last Post: 12-16-2004, 07:16 AM