This topic is 3728 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Anyone see something wrong with this code that would prevent the << operator overload from working? Here's the error I get during compile: Error error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,struct product const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABUproduct@@@Z) already defined in main.obj order.obj 5 And here's the code for the struct:

/*
struct that contains information for individual products
*/

#ifndef PRODUCT_H
#define PRODUCT_H

#include <string>
#include <iostream>

using namespace std;

struct product
{
int productID;
string productName;
string productDescription;
double unitCost;
string department;

friend ostream& operator<<(ostream&, const product&);

};

ostream& operator<< (ostream& osObject, const product& productObject)
{
osObject << "#BEGINREC#" << endl;
osObject << productObject.productID << endl;
osObject << "#ENDREC#" << endl;
return osObject;
}

#endif


Additional info: I'm using the same code pretty much for several classes and the overload works for them, the struct is the only one that fails. I also do not have anything in main.cpp regarding overloading. The only places where this code resides is in the working classes and this one non-working struct

##### Share on other sites
Don't put the implementation in the header file. Put it in a matching source file instead.

##### Share on other sites
Put the definition of the overloaded function into its own source file so that you don't get the already defined error! Alternatively you could declare it inline and leave it in the header file.

##### Share on other sites
Freaking awesome that worked like a charm. Now I have to ask, why did that have an effect? My understanding, and please correct me if / where I'm wrong, is that seperating the .h and .cpp files is nice for reading and seperating definitions from declarations but that it had no effect on the actual functionality.

##### Share on other sites
Quote:
 Original post by furin591Freaking awesome that worked like a charm. Now I have to ask, why did that have an effect? My understanding, and please correct me if / where I'm wrong, is that seperating the .h and .cpp files is nice for reading and seperating definitions from declarations but that it had no effect on the actual functionality.

It has an effect on the compilation process, since each header file is copied, as is, into each implementation (.cpp) file that includes it. Since your implementation files are compiled to produce object files (.obj), and your object files are linked to yield static import libraries (.lib) or executables (.exe, .dll), having the same function in two implementation files tries to put two definitions into the final library/executable. Which yields LNK2005.

Header files are for declarations, not definitions, except for class definitions but not class member function definitions (which is a stupid thing, if you ask me). And it would all be made moot - and header files would disappear -if C++ employed a multi-pass compilation process, but it doesn't.

##### Share on other sites
Quote:
 Original post by OluseyiIt has an effect on the compilation process, since each header file is copied, as is, into each implementation (.cpp) file that includes it. Since your implementation files are compiled to produce object files (.obj), and your object files are linked to yield static import libraries (.lib) or executables (.exe, .dll), having the same function in two implementation files tries to put two definitions into the final library/executable. Which yields LNK2005.

Ok, I'm going to sound like a complete idiot but I have to ask: if compilation basically copies the header into the implementation file, how is that different from just putting it all into one file to start with? And if you just have a header file, like I had in this case, does the system create a generic imp file for you without your knowledge that includes the operators (my best guess is that it does and that that ultimately is where my problem was)?

Sorry if these are annoying questions but I really want to understand the problem and not just have a 'fix' for it, ya know?

##### Share on other sites
Quote:
 Original post by furin591Ok, I'm going to sound like a complete idiot but I have to ask: if compilation basically copies the header into the implementation file, how is that different from just putting it all into one file to start with?

You can include a header in multiple implementation files. That saves you writing the same code - or copy-pasting it - over and over again. Also, with inclusion guards, the preprocessor will ensure that a header is not copied twice into a given implementation file. Thirdly, you can include headers in headers.

Quote:
 And if you just have a header file, like I had in this case, does the system create a generic imp file for you without your knowledge that includes the operators (my best guess is that it does and that that ultimately is where my problem was)?

The compiler doesn't care about header files. It is the preprocessor that handles copying them into the implementation file, to create one large translation unit to be fed into the compiler. Note that you pull header files into implementation files via #define, and all directives beginning with a # sign are handled by the preprocessor.

If you don't have any implementation files, you can't compile. I mean, sure, you can force the compiler to compile your header - command line interfaces don't always pay as much attention to filename extension - but a VC++ project won't enable the compile button, menu option or shortcut unless you have an implementation file available. So, no, the system doesn't generate a generic implementation file for you.

Quote:
 Sorry if these are annoying questions but I really want to understand the problem and not just have a 'fix' for it, ya know?

That's a fantastic attitude to have! Just remember to balance understanding against deadlines! [smile]

##### Share on other sites

This topic is 3728 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628732
• Total Posts
2984436

• 25
• 11
• 10
• 16
• 14