oldabl
oldabl

Reputation: 388

How can I use a member function of a forward declared class?

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

Answers (3)

Antho A
Antho A

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

anatolyg
anatolyg

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

David Haim
David Haim

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:

  1. We don't have cyclic inclusion (a header file which includes another header file, which includes the original)
  2. Each class implementation "sees" how the other class looks like, but not how it's implemented, we don't break "separation of interface from implementation" rule. there are some cases where we don't do that, but for most cases, it's valid.

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

Related Questions