Multiple definition error (dev C++)

Started by
9 comments, last by jflanglois 16 years, 10 months ago
Hello Everyone, I'm trying to create a vector class that will hopefully make my game development easier. Anyways, I created my vector class and put all the source code in vectorClass.h, then I put that header in my Dev C++ include directory so that Whenever I want to use it, i can just #include <vectorClass.h> and be on my way. Here's the problem. I can only include that file in one of my .cpp files. If i have it included in more than one file, it gives me this error for all the methods in my class: Multiple definition of vectorClass:methodname(...) I tried putting: #ifndef _VECTORCLASS_H_ #define _VECTORCLASS_H_ #endif around the code in my header file, but it still doesn't seem to do anything. Anyone know what I can do about this? Thanks Gavin
-------------------------------------Physics Labhttp://www.physics-lab.netC++ Labhttp://cpp.physics-lab.net
Advertisement
Quote:
I tried putting:

#ifndef _VECTORCLASS_H_
#define _VECTORCLASS_H_

#endif

around the code in my header file, but it still doesn't seem to do anything.

Yes it does. It just doesn't do what you want. These so-called "include guards" only protect against multiple-inclusion within a single translation unit (a translation unit is essentially a source file plus the contents of the extra files injected by #include directives and other preprocessor majiks). Basically, include guards prevent errors when you do "#include <foo> #include <foo>" (which is a trivial case, but in practice can happen if you include foo, and then include bar, which includes baz, which includes foo, and so on).

The problem with your vector class header is most likely that you've provided definitions of non-inline functions, or variables, et cetera, in the header. Since each translation unit is compiled in isolation, each translation units gets a copy of said functions or variables, which means when the linker ultimately assembles the object files produced by the compiler, it will find multiple definitions for some symbols, which violate C++'s "one definition rule," and thus cause the linker to complain and abort.

Unfortunately this makes things a wee bit tricky for you; the proper solution is to move definitions into a source file. But if you did this, you'd no longer be able to include the vector file as easily, because you'd also have to add the vector source file to your project every time. You could make all the methods inline, but this is an iffy solution that does not scale well. Another option is to turn the vector class (and perhaps other related classes) into a library and place the library in your IDE's library search paths, and link with that. Et cetera. There are a number of variations on these ideas you could apply to fix the problem, and which makes most sense to you depends on the style of your projects and development environment.
try adding

#pragma once at the top of your h file instead of using the #ifndef include guards. Note: Some compilers don't handle #pragma once very well, but VS should have no issue at all.
try adding

#pragma once

at the top of your h file instead of using the #ifndef include guards. Note: Some compilers don't handle #pragma once very well, but VS should have no issue at all.
The symbol _VECTORCLASS_H_ is reserved for the compiler.

Symbols that follow these rules are reserved:

1) begin with 2 underscores

2) begin with a single underscore and a capital letter


So, use #ifndef VECTORCLASS_H, not only is it standard, it is quicker to type.

This is very unlikely to be the source of your error though, see jpetrie's post for that.
I'm going out on a limb here, because I've seen it so often:

Do you declare your class like this? :

// foo.hclass Foo {  int a;  string s;  // Constructor  Foo() {    a = 2;    b = "Frogs";  }  int addMoreFrogs(int num_frogs);};// foo.ccint Foo::addMoreFrogs(int num_frogs) {  return ++a;}


I see a lot of people who generally separate their definitions and declaration except for "that one thing" which didn't seem to be a problem.

If you have more than one file that includes "foo.h" then when each file is compiled into object code, it has a definition of the constructor, in this case. Then when they are linked, you suddenly have multiple definitions, and it's obvious to the uninitiated why.

So, like most of my responses, it comes down to: "Show me the source."

Edit: Missed the closing source tag first time around.

[Edited by - erissian on June 22, 2007 7:38:33 AM]
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Do tell, why aren't you using std::vector?

But to answer your question, you probably have your non-inline member definitions in the header, which causes multiple redefinition when you include that header in several translation units (edit: err, see jpetrie's post). If that didn't make any sense to you, then I point you to the obligatory Organizing Code Files in C and C++.


jfl.
@erissian, such a definition causes no problem because it is within the class body and therefore implicitly inline.

Quote:Original post by jflanglois
Do tell, why aren't you using std::vector?


It might be a vector in the geometrical sense?

Quote:the obligatory Organizing Code Files in C and C++.


You know, just in case. ;)
Quote:Original post by Zahlman
@erissian, such a definition causes no problem because it is within the class body and therefore implicitly inline.


Ah, that's true... I suppose the constructor was the worst example to make my point with :D
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Quote:Original post by jflanglois
Do tell, why aren't you using std::vector?

jfl.


Oh, my vector class is for mathematical vectors, not the vector data structure :)


Thanks for all your input guys, I'll read that article and see what I can do. If I can't make it work the way I want it, I might just compile it into a library and use it that way!

Cheers!
-------------------------------------Physics Labhttp://www.physics-lab.netC++ Labhttp://cpp.physics-lab.net

This topic is closed to new replies.

Advertisement