Jump to content
  • Advertisement
Sign in to follow this  
heidiann

Already defined object, where?

This topic is 2754 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

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


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

Share this post


Link to post
Share on other sites
This looks like your problem:class Foo // defines a new class called Foo
{
...
}Foo;//Makes a new Foo object called Foo
The above is equivalent to:class Foo// defines a new class called Foo
{
...
};

Foo Foo;//Makes a new Foo object called Foo
The 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 this post


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


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


Link to post
Share on other sites

This looks like your problem:class Foo // defines a new class called Foo
{
...
}Foo;//Makes a new Foo object called Foo
The above is equivalent to:class Foo// defines a new class called Foo
{
...
};

Foo Foo;//Makes a new Foo object called Foo
The 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 this post


Link to post
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 Foo
The above is equivalent to:class Foo// defines a new class called Foo
{
...
};

Foo Foo;//Makes a new Foo object called Foo
The 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 this post


Link to post
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 Foo
The above is equivalent to:class Foo// defines a new class called Foo
{
...
};

Foo Foo;//Makes a new Foo object called Foo
The 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 :D, just as your "static class" would be.

Share this post


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


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!