Reputation: 388
I have 2 classes A and B and the 4 following files:
A.h
#ifndef A_H
#define A_H
#include "B.h"
class A {
public:
A();
int functionA();
B objectB;
};
#endif //A_H
B.h
#ifndef B_H
#define B_H
class A;
class B {
public:
B();
int functionB();
A * objectA;
};
#endif //B_H
A.cpp
#include "A.h"
A::A(){}
int A::functionA() {
return 11;
}
B.cpp
#include "B.h"
B::B(){}
int B::functionB() {
return objectA->functionA();
}
Now I compile using the line: g++ A.cpp B.cpp -Wall -Wextra -O2 -march=native -std=gnu++1z
I get this error:
B.cpp: In member function 'int B::functionB()':
B.cpp:4:19: error: invalid use of incomplete type 'class A'
return objectA->functionA();
^
In file included from B.cpp:1:0:
B.h:1:7: note: forward declaration of 'class A'
class A;
^
How can I use a member class of the function forward declared here?
Upvotes: 4
Views: 3763
Reputation: 78
Look at what is included when compiling B.cpp
, you have a forward declaration of class A
but not the real definition. So in B.cpp
on line 4, functionA
is unknown to the compiler therefore your type is incomplete.
You should include A.h
in B.cpp
.
Upvotes: 3
Reputation: 28251
Using members of a class with only a forward declaration is impossible.
If your code uses a member function, the class should be fully declared, because the compiler needs to check that the member function with this name actually exists.
Upvotes: 1
Reputation: 26496
In A.cpp
, Include both A.h
and B.h
In B.cpp
, Include both B.h
and A.h
.
It works because:
The thumb rule (only a thumb rule!) is to include the class header in every .cpp
file which uses that class. so if foo.cpp
uses the class bar
, and class bar
interface is in bar.h
, then foo.cpp
should include bar.h
. There are some specific cases we don't follow that rule, but for the most cases, it's valid.
Upvotes: 2