I tested the Chapter 16's code from "C++primer"(4 Edition) in CFree5, but got redefinition errors. Here is the inclusion relations:
file:MS_Queue.h
1 2 3 4 5 6 7 8 9 10
#ifdef QUEUE_H
#define QUEUE_H
#include<iostream>
template<class type> class Queue<type>; //declaration
template<class type> class QueueItem<type>{ ... }; //definition
// That the Queue class declaration precedes class QueueItem definition is because he makes Queue a friend of QueueItem
template<class type> class Queue<type>{ ... }; //definition
... //something else
#include "MS_Queue.cpp"
#endif
file"MS_Queue.cpp"
1 2 3 4 5 6 7 8 9 10
#include "MS_Queue.h" /* Here is where i suspects , I don't understand, if MS_Queue.h includes MS_Queue.cpp , then MS_Queue.cpp includes MS_Queue.h, does
this results a infinite inclusion between MS_Queue.h and MS_Queue.cpp? Taking into the consideration of Header Guard, should i omit the directive "#include
"MS_Queue.h" in the MS_Queue.cpp file? */
#include <stdexcept>
using std::out_of_range;
#include <iostream>
using std::ostream;
template<class T> void Queue<T>::copy_elems( const Queue& rhs )
{ ...};//definition
... // 5 more template member functions of Queue
When i complied in CFree5, i got the redefintion error:
1 2
[Error] E:\..\MS_Queue.cpp:9: error: redefinition of `void Queue<Type>::copy_elems(const Queue<Type>&)'
[Error] E:\...\MS_Queue.cpp:9: error: `void Queue<Type>::copy_elems(const Queue<Type>&)' previously declared here
Notice the error appears in the SAME line!!! What's wrong???
Please help me! Thanks!
But, this is called "Inclusion compilation model", the author said.
And if i comment out the directive '#include "MS_Queue.cpp" ' in MS_Queue.h, all the occurences of copy_elems() will be reported undefined.
What's the problem?
Change MS_Queue.cpp to MS_Queue.hpp or MS_Queue_implementation.h
The include just copy-paste the content of the file, so you will have access to the template definition (needed).
1 2
//MS_Queue.hpp
#include "MS_Queue.h"
There is no problem with that because it is header guarded. #ifndef QUEUE_H (note: you have the opposite). You could delete it if you want.
Keep in mind that the client sources will need to include the file with the declarations (the .h)
The error is caused because you are trying to compile MS_Queue.cpp (g++ -c MS_Queue.cpp), then you end with 2 copies of every definition.
Really!!! It works!!!
Now I understand, I just tried to compile all three files: "MS_Queue.h","MS_Queue.cpp" and "Main.cpp" while "MS_Queue.h" includes "MS_Queue.cpp". After deletion in project of CFree5, It worked.
But why should i rename the MS_Queue.cpp to MS_Queue.hpp ? Does this matter, ne555 ?
Now, I am annoyed by another problem: you see, i have three files , MS_Queue.h, MS_Queue.cpp, Main.cpp, as we all know, any file that uses Queue should include MS_Queue.h, and header files should be included by .cpp files, as a consequence, Main.cpp file only includes MS_Queue.h and MS_Queue.cpp only includes MS_Queue.h , when compile, how does the compiler see MS_Queue.cpp which is the implementation of Queue , after all ,the header and the Main file don't and aren't supposed to include it ?
All right, it's a silly question.
Anyway, i rename the implementation file "MS_Queeu.hpp" and include the "MS_Queue.h", thus, when i need to use Queue class, i just need to include "MS_Queue.hpp".
It's a good idea.
I had a similar problem but I had declarations and definitions in one header file.
The compiler stated I wanted to redefine function and sent me to previously defined which was the same line.
When I moved definitions to another .hpp file and included that file in the main file everything started working. But I still don't know why..