2

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

w.izzy
  • 21
  • 4

3 Answers3

0

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

Top Sekret
  • 748
  • 5
  • 21
0

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

Community
  • 1
  • 1
w.izzy
  • 21
  • 4
-1

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).

  • unfortunately this produces the following error: "out-of-line declaration of 'doSomething' does not match any declaration in 'A'" – w.izzy Jan 24 '17 at 14:51
  • You need to have the definition of `B` before you can _use_ `B` (whether by declaring a variable of type `B`, or by using a member of `B`). You only need a declaration for `B` to declare a _pointer or reference_ to `B`. See [this example](http://ideone.com/2O5qfU). (This is because the members of `B` need to be known to compute the size of `B` or allow them to be used, but the size of a pointer generally isn't modified by the members (and references officially aren't actual entities so much as new names for pre-existing entities, but are typically implemented via pointers).) – Justin Time - Reinstate Monica Jan 24 '17 at 18:59