I have a class (A) which has to include two files, class X and class Y. unfortunately class Y also needs to include class X in it's header file because the constructor takes a pointer to a class X type as an argument.
The potential problem is that there would be a linker error? as class A now has two copies of class X in it, one that it needs to use, and one from class Y. This is the situation where header guards are of no use. My question is - is this purely a structural problem or is there a way around this?
I really would prefer to not include anything in class Y's header file, in case I want to include THAT in anything else, but is it necessary because of the function prototype?
This error can occur when a header file defines a function that isn't inline . If you include this header file in more than one source file, you get multiple definitions of the function in the executable. To fix this issue, move the member function definitions inside the class.
Without a header guard, a code file could end up with multiple (identical) copies of a given type definition, which the compiler will flag as an error.
Header Guards in C++ are conditional compilation directives that help to avoid errors that arise when the same function or variable is defined more than once by the mistake of a programmer. According to C++, when a function or a variable is defined more than once, it yields an error.
No. If you import the same header from two files, you get redefinition of function. However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
If you have the following:
X.h
#ifndef X_H__
#define X_H__
class X
{
public:
int foo() { return 1; }
};
#endif
Y.h
#ifndef Y_H__
#define Y_H__
#include "X.h"
class Y
{
public:
Y(X *pX) { myval = pX->foo(); }
int myval;
};
#endif
something.cpp
#include "X.h"
...
something_else.cpp
#include "Y.h"
...
Then there should be no problem.
However, if X.h
instead looks like this:
#ifndef X_H__
#define X_H__
class X
{
public:
int foo();
};
int X::foo() { return 1; }
#endif
then you will indeed get a linker error when you try to link something.cpp
and something_else.cpp
. X::foo
will have been defined non-inline into two separate translation units.
You can use a declaration in the Y header.
class X;
Since you only use a pointer to X the compiler doesn't need to know it's definition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With