Multple c++ files causes “multiple definition” err

2019-07-30 14:54发布

I'm using multiple C++ files in one project for the first time. Both have need to include a protected (#ifndef) header file. However, when I do that, I get a multiple definition error.

What I have is two one .cpp file that calls the header directly, and one indirectly (Another include includes it) and then two other header files that include it.

So what do I need to do to get rid of the error?

ERROR:

obj\Debug\main.o||In function Z14sortLibQtyTest4BookS_':| [PATH]\miscFuncs.h|16|multiple definition ofsortLibQtyTest(Book, Book)'

CODE:

bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }

It should be mentioned that this isn't the only function giving me problems, probably more than ten are, and some aren't so short and sweet. Also, the functions are needed in multiple files.

3条回答
何必那么认真
2楼-- · 2019-07-30 14:56

The ".cpp" and ".h" suffixes are largely a matter of convention. As far as the compiler is concerned, where a line of code came from is irrelevant. When you #include that function into your .cpp files, you are implementing that function in that .cpp file.

So when the compiler is done and it asks the linker to knit together the code from your two cpp files, it finds a conflict: two functions with the same name and fingerprint (arguments and return). This is an error.

You need to either:

a. Put the implementation in one source file, and just leave a prototype declaration in the header

// .h
extern bool sortLibQtyTest(Book a, Book b);

// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }

b. Mark the function as inline: when you call the function, the compiler will insert copies of the function body as needed which can be wasteful, but often times the compiler can figure out the efficient thing to do.

inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }

c. Mark the function as "static" which tells the compiler to create a copy of the function for every source file that includes it, but not to expose it to the linker. If some source files include the header without using the function, the compiler has to detect this and remove it - which not all compilers/optimization levels do, so it can be doubly wasteful.

static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }

d. Avoid the downsides of c, mark it static inline

static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
查看更多
Anthone
3楼-- · 2019-07-30 14:59

If the Line you quoted after "CODE" is in a header file you can either:

  • add inline to the definition or
  • remove the function body from the header and put it into 1 (and only 1) of your source files.
查看更多
贼婆χ
4楼-- · 2019-07-30 15:19

You have two options to solve this multiple definition problem: Mark the method inline, or put the definition in a .cpp file.

1) Mark the method inline:

// Foo.h

inline bool foo(int i) { return i = 42; }

2) Put the definition in a .cpp file:

// Foo.h

inline bool foo(int i); // declaration

// Foo.cpp
bool foo(int i) { return i = 42; } // definition

Whether the method is actually inlined by the compiler in the first case is irrelevant here: inline allows you to define a non-member function in a header file without breaking the one definition rule.

查看更多
登录 后发表回答