Sign in to follow this  

operator overloading in a struct

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

If you intended to correct an error in the post then please contact us.

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:

/*
	product.h header file
	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;


	 //operator overload
	 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by furin591
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.

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 this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
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.



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 this post


Link to post
Share on other sites
Quote:
Original post by furin591
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?

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 this post


Link to post
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.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this