After learning more about classes and pointers, I refactored a program I had and wiped out > 200 lines of code, in the process creating two other classes, Location
and Piece
. The problem is, after getting everything to compile, the linker complains that the constructor for Piece
is defined multiple times, with a load of errors:
In function 'Piece': board.o
multiple definition of 'Piece::Piece(int)` char_traits.h
In function 'Piece': board.o
multiple definition of 'Piece::Piece(int)` piece.cpp
In function 'Piece': player.o
multiple definition of 'Piece::Piece(int)` piece.cpp
In function 'Piece': player.o
multiple definition of 'Piece::Piece(int)` piece.cpp (yes, same exact error!)
In function 'Piece': refereee.o
multiple definition of 'Piece::Piece(int)` char_traits.h
In function 'Piece': referee.o
multiple definition of 'Piece::Piece(int)` piece.cpp
...
When I click on the error for char_traits.h
, it brings me to this:
static size_t
length(const char_type* __s) //error points here to line 262
{ return __builtin_strlen(__s); }
Another char_traits.h
brings me to
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n) //line 258, error points here too
{ return __builtin_memcmp(__s1, __s2, __n); }
And just so you know, location.h is the only thing that includes piece.h (well, other files include piece.h indirectly from location including piece.h), board.h is the only thing that includes location.h, and a bunch of classes include board.h
I tried changing the header guard to _OTHELLO_PIECE_H
, and tried renaming the class to OPiece (via the IDE). Neither fixed the problem.
The funny thing is, one of the errors has an "in function 'OPiece':", and after that my IDE puts chatter.o
, even though neither chatter.h nor chatter.cpp includes anything that includes OPiece.
Any idea what might be causing this redefinition error?
- Rebuild everything
- Look for Piece::Piece, and remove all such from header files 2b. Never #include .cpp files
- Look for #define that resolves to Piece
The most common cause of a multiple function definition error is putting a function definition in a header file and forgetting to make it inline
.
I wouldn't worry much about char_traits.h
- this probably means that because of some template runaround, the linker couldn't figure out a better place to claim the definition happened in that particular object file.
You should put the implementation of the constructor in piece.cpp
, not directly in piece.h
.
there are two places to implement Piece::Piece(int)
in a typical build:
1) the interface (at declaration)
class Piece {
int d_a;
public:
Piece(int a) : d_a(a) {
}
/* ... */
};
2) in a dedicated cpp file
in Piece.hpp
class Piece {
int d_a;
public:
Piece(int a);
/* ... */
};
in Piece.cpp
Piece::Piece(int a) : d_a(a) {
}
however, templates are defined differently.
the error often indicates that Piece::Piece(int a) : d_a(a) {}
is included in multiple cpp files.
each object file produced adds the symbol Piece::Piece(int)
where it is visible.
at the end of the build, all objects are merged/linked to create your final binary or executable. then the linker sees that there are copies of this definition and produces an error.
one quick way to diagnose this is (assuming your builds do not take long):
#warning Piece::Piece(int) is visible here
Piece::Piece(int a) : d_a(a) {
}
exactly one warning should be emitted. if more are emitted, then the compiler will likely provide a bit of information (such as the include order).
Just a guess: Did you use #include
or did you use #import
by accident -- which happened to me once :-)
来源:https://stackoverflow.com/questions/4054357/multiple-redefinition-error