forward declaration in two headers and two cpp files

1.9k views Asked by At

I have four C++ files, two headers and two cpp. The headers are properly guarded and in the first I use a forward declaration like this:

//A.h
class B;

class A {
public:
    A();
    void doSomething(B* b);
};

and some implementation:

void A::doSomething(B* b){
    b->add();
}

the other header is as follows:

#include "A.h"
class B {
public:
    B();
    void add();
};

and

void B::add(){
    cout << "B is adding" << endl;
}

I get the "member access into incomplete type B" error and I'm stuck in there. I need to use a of Bs into A and each B must have a pointer to its "owner", an instance of A. What can I do to solve this situation.

Thanks in advance

3

There are 3 answers

2
Brooke Elizabeth On

You need to have the definition for class B before you can use the doSomething(B* b) method, so I think instead of:

class B;

class A {
public:
    A();
    void doSomething(B* b);
};

you would need to do something like:

class B;

class A {
public:
    A();
};

void A::doSomething(B* b);

declaring it after so the compiler has the information it needs about class B (memory allocation, etc).

1
Top Sekret On

The B.cpp file, despite named similarly, does not implicitly include B.h. You have to include the B.h from both implementations. Also, if you want to include both A.h and B.h, create the include guards

0
w.izzy On

solved the issue by using forward declarations in both A and B class definitions (headers) and including A.h in B.cpp and also B.h in A.cpp. Here's the code:

//A.h

#ifndef A_H_
#define A_H_

#include <iostream>

using namespace std;

class B;

class A{
public:
    A();
    virtual ~A();

private:
    B* pToB;

public:
    void doSomething(B* b);
    void SetB(B* b);
};

#endif

The cpp for A class, note the inclusion of B.h (this I wouldn't normally do)

// A.cpp

#include "A.h"
#include "B.h"

A::A():pToB(){
    cout << "A constructor" << endl;
}

A::~A(){}

void A::SetB(B* b){
    this->pToB = b;
    cout << "setting B" << endl;
}

void A::doSomething(B* b){
cout << "A is gonna call B's method add: ";
    b->add();
}

now the B class:

// B.h

#ifndef B_H_
#define B_H_

#include <iostream>

using namespace std;

class A;

class B{
public:
    B();
    virtual ~B();

private:
    A* pToA;

public:
    void add();
    void SetA(A* a);
};

#endif

implementation for B

// B.cpp

#include "B.h"
#include "A.h"

B::B():pToA(){
    cout << "B constructor” << endl;
}

B::~B(){}

void B::SetA(A* a){
    this->pToA = a;
    cout << "setting A" << endl;
}

void B::add(){
    cout << "B is adding" << endl;
}

the cpp including main function (both headers included, did not include )

#include "A.h"
#include "A.h"

int main() {
    A* newA = new A;
    B* newB = new B;
    newA->SetB(newB);
    newB->SetA(newA);
    newA->doSomething(newB);
    return 0;
}

the output for this programme is like this:

A constructor
B constructor
setting B
setting A
A is gonna call B's method add: B is adding

thanks to Sandeep Datta whose solution helped me to solve this issue