Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ previous definition error

Tags:

c++

include

class

So, thanks to this website, I found the answer to my previous problem. I'm adding a function to a class in a GNU automake project that uses a pointer to a doc object. Dependencies were included in the Makefile.am file to include doc.h and plsa.h in the respective order. However, when I compiled, I would get a doc has not been declared error. Then, I tried adding the #include statement here, which gives a previous redefinition of 'class doc' error.

I learned that I have to declare doc by using the class doc; line commented out below; however, I thought that this was only necessary if I was declaring a function that passes the object by value. Can someone explain to me why the #include is incorrect in this case?

#include "doc.h"
//class doc;
class plsa {
    // ...
    int infer(doc *trset, int maxiter, double noiseH);
}
like image 203
Nick Ruiz Avatar asked Oct 27 '11 17:10

Nick Ruiz


2 Answers

Why the Redefinition errors?
Please ensure that your header files have appropriate Header Guards/Include Guards.It is most likely that you have missed adding header guards and hence that causes multiple class definitions due to the header getting included multiple times.

Why Forward Declaration is okay in this case?
When instead of including the header file you add the line:

class doc;

It Forward declares the class doc which means for compiler it is an Incomplete type. With Incomplete types, One cannot create objects of it or do anything which needs the compiler to know the layout of docor more than the fact that doc is just an type. i.e: The compiler does not know what are its members and what its memory layout is.
But Since pointers to all objects need just the same memory allocation, You can use the forward declaration when just reffering to an Incomplete type as a pointer.

In this case the only way in which doc is being referenced is an pointer to the class doc and hence the Forward declaration will work as well.

BottomLine:
Including the header file should work for you If you have proper Inclusion Guards in-place. And there is nothing wrong with it.
However, Forward declaring the class should also work for you because of the reasoning given above.Note that forward declarations are usually used in case where there is a Circular Dependency of classes.

Which is better Include header File or Forward Declaration?
Including the header file just copy pastes the code from the header to wherever the file was included, which basically could lead to:

  • Increase in compilation time
  • Pollution of global namespace.
  • Potential clash of preprocessor names.
  • Increase in Binary size(in some cases though not always)

Forward Declaration has its own limitations on how the Incomplete type can be used further on.
With Incomplete type you can:

  • Declare a member to be a pointer or a reference to the incomplete type.
  • Declare functions or methods which accepts/return incomplete types.
  • Define functions or methods which accepts/return pointers/references to the incomplete type (but without using its members).

With Incomplete type you cannot:

  • Use it as a base class.
  • Use it to declare a member.
  • Define functions or methods using this type.

Given the possibility(due to above limitations on Incomplete type usage) One should prefer Forward Declaration over Including Header.

like image 183
Alok Save Avatar answered Oct 05 '22 06:10

Alok Save


You are missing include guardians. if you just include files they are just pasted you need to make sure when they are included multiple times that they other times the code isn't duplicated. so you use a construct like this.

 #ifndef _XXX_
 #define _XXX_
    /* your header here */
 #endif
like image 23
Alexander Oh Avatar answered Oct 05 '22 08:10

Alexander Oh