Public Group

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

## Recommended Posts

I have been going over and over what could be wrong and I cannot figure out why I am getting these errors. Can someone please help me I have read MSDN, many many links but non of them help me out.

Errors
 Error 1 error LNK2005: "class Foo Foo" (?Foo@@3V0@A) already defined in Bar.obj Error 2 error LNK1169: one or more multiply defined symbols found 

Bar.hpp
 #ifndef _BAR_HPP #define _BAR_HPP class Foo { public: Foo(); ~Foo(); void SetInt(const int&); int GetInt(); int var; }Foo; class Bar { public: Bar(const int&); ~Bar(); int GetInt(); private: }; #endif 

Bar.cpp
 #include "Bar.hpp" Foo::Foo() { var = 0; } Foo::~Foo() { var = 0; } void Foo::SetInt(const int& value) { var = value; } int Foo::GetInt() { return var; } Bar::Bar(const int& value) { Foo.SetInt(value); } Bar::~Bar() { } int Bar::GetInt() { return Foo.GetInt(); } 

Main.cpp
 #include <iostream> #include "Bar.hpp" using namespace std; int main(int argc, char* argv[]) { Bar bar(25); cout << "Bar: " << bar.GetInt() << endl; return 0; } 

##### Share on other sites
Are you sure you want "} Foo;" instead of "};" at the end of your Foo class definition?

##### Share on other sites
This looks like your problem:class Foo // defines a new class called Foo { ... }Foo;//Makes a new Foo object called FooThe above is equivalent to:class Foo// defines a new class called Foo { ... }; Foo Foo;//Makes a new Foo object called FooThe result of this is the every CPP file that includes "Bar.hpp", will create a new global variable called "Foo". Thus, both Main.cpp and Bar.cpp have global Foo objects, named Foo, and the linker is complaining that the global Foo object exists twice...

##### Share on other sites
I was thinking of having a static class but not sure exactly how I would go about it. So I am trying this which works but it doesn't seem like it is the best method, any other ways that would be more efficient?

Bar.hpp
 #ifndef _BAR_HPP #define _BAR_HPP namespace Foo { extern int var; void SetInt(const int&); int GetInt(); } class Bar { public: Bar(const int&); ~Bar(); int GetInt(); private: }; #endif 

Bar.cpp
 #include "Bar.hpp" namespace Foo { int var = 0; void SetInt(const int& value) { var = value; } int Foo::GetInt() { return var; } } Bar::Bar(const int& value) { Foo::SetInt(value); } Bar::~Bar() { } int Bar::GetInt() { return Foo::GetInt(); } 

##### Share on other sites
C++ doesn't need static classes, it has free functions. You shouldn't need global mutable state. It is hard to propose good alternatives without a concrete example, but a typical approach is to wrap the shared data in a class to protect any invariants, and pass some kind of reference to an instance of this class to other classes that need it.

Note that your include guards clash with those reserved for the compiler. Using the shorter "BAR_HPP" form is safer (i.e. drop the leading underscores).

##### Share on other sites

This looks like your problem:class Foo // defines a new class called Foo { ... }Foo;//Makes a new Foo object called FooThe above is equivalent to:class Foo// defines a new class called Foo { ... }; Foo Foo;//Makes a new Foo object called FooThe result of this is the every CPP file that includes "Bar.hpp", will create a new global variable called "Foo". Thus, both Main.cpp and Bar.cpp have global Foo objects, named Foo, and the linker is complaining that the global Foo object exists twice...

Hm... Not sure about that. Shouldn't the include guards prevent the linker from that??

##### Share on other sites

[quote name='Hodgman' timestamp='1299648505' post='4783414']
This looks like your problem:class Foo // defines a new class called Foo { ... }Foo;//Makes a new Foo object called FooThe above is equivalent to:class Foo// defines a new class called Foo { ... }; Foo Foo;//Makes a new Foo object called FooThe result of this is the every CPP file that includes "Bar.hpp", will create a new global variable called "Foo". Thus, both Main.cpp and Bar.cpp have global Foo objects, named Foo, and the linker is complaining that the global Foo object exists twice...

Hm... Not sure about that. Shouldn't the include guards prevent the compiler about that??
[/quote]
Include guards don't reach across translation units; they only prevent the inclusion of headers multiple time within a single translation unit. They prevent the compiler from complaining about redefinitions, but it won't do anything about the linker complaining about multiple definitions.

##### Share on other sites

[quote name='domUrob' timestamp='1299675594' post='4783526']
[quote name='Hodgman' timestamp='1299648505' post='4783414']
This looks like your problem:class Foo // defines a new class called Foo { ... }Foo;//Makes a new Foo object called FooThe above is equivalent to:class Foo// defines a new class called Foo { ... }; Foo Foo;//Makes a new Foo object called FooThe result of this is the every CPP file that includes "Bar.hpp", will create a new global variable called "Foo". Thus, both Main.cpp and Bar.cpp have global Foo objects, named Foo, and the linker is complaining that the global Foo object exists twice...

Hm... Not sure about that. Shouldn't the include guards prevent the compiler about that??
[/quote]
Include guards don't reach across translation units; they only prevent the inclusion of headers multiple time within a single translation unit. They prevent the compiler from complaining about redefinitions, but it won't do anything about the linker complaining about multiple definitions.
[/quote]

Thanks! That's the point! And then that's why the code is wrong. Since the header is declaring data instead of only defining types... You have the same global definition on each translation unit in which you include the header. There you have your linker screwed up.

The only way I see for this to be possible is to declare your Foo instance as static. Then it will only have scope inside each translation unit. But BE AWARE of the fact that there is a different instance for each time you include your header.

The namespace approach is already maximum performance , just as your "static class" would be.

##### Share on other sites
I didn't even see the comment from the OP about efficiency. The most efficient solution is to avoid such data dependencies. It depends on the nature of the "var", what it is used for, how often it is used, the ratio of reads/writes and on a lot of other things.

##### Share on other sites
Thanks for all the information the reason I am using this example is to spare the extreme amount of code in the actual program so I minimized it by using a Foo, Bar example. I did however resolve the issue after realizing it wasn't my code being complex but the fact that is was a basic problem I should have known about. In my real code I am using FMOD and what would be in the namespace Foo on my follow-up post would be the FMOD::system*, result, etc... stuff that doesn't need to be initialized more than once but is required to be used in a Music class and a Effect class, In all honesty I could probably modify it to be only one class, but there is a difference in loading a sound and a stream, even though multiple file formats could be loaded either way.

C++ doesn't need static classes, it has free functions. You shouldn't need global mutable state. It is hard to propose good alternatives without a concrete example, but a typical approach is to wrap the shared data in a class to protect any invariants, and pass some kind of reference to an instance of this class to other classes that need it.

Note that your include guards clash with those reserved for the compiler. Using the shorter "BAR_HPP" form is safer (i.e. drop the leading underscores).
[/quote]

Just curious if C++ doesn't need static classes, why does cplusplus.com have an example on the usage of "static"? Is that site wrong for showing a use of something not needed in that specific language? Also thanks for the tip on the '_' So many bad examples out there a long the learning road. I have really disconnected from tutorial sites though over time as I have noticed a lot of bad practices a long the way, but only after I look back. The site Cplusplus.com isn't in that mix since they are not tutorials really, just example usage in the basic.

1. 1
2. 2
3. 3
4. 4
5. 5
Rutin
18

• 11
• 12
• 9
• 12
• 37
• ### Forum Statistics

• Total Topics
631420
• Total Posts
2999990
×