0

What I have is 2 classes:

A.h:

#include "B.h"
class A
{
    vector<B*> arr;
    void Update(int32 id){...};
}

B.h

#include "A.h"
class B
{
    int32 id;
    A* parent;
    void OnRemove()
    {
        ...
        parent->Update(id);
    }
}

With that logic everything must work fine as expected. But it won't because of loop include: A.h including B.h and B.h including A.h

The question is how to make it working with that structure of code or other.

Main feature that should exist is to call event in A object which is holding B object.

Every help would be appreciated.

Alxspb
  • 35
  • 6
  • 2
    Not 100% sure but it looks like this is a dupe of: https://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies – NathanOliver Jul 18 '17 at 18:34

2 Answers2

1

the usual way is to provide guarding macros to prevent recursion and move definition of functions in a separate file if needed:

a.h

#ifndef _A_H_
#define _A_H_
#include "B.h"
class A
{
  vector<B*> arr;
  void Update(int32 id){...};
} 
#endif

...

c.cpp (if needed)

#include <a.h>
#include <b.h>

void B::onRemove() {
   blahblahblah
}
Serge
  • 11,616
  • 3
  • 18
  • 28
  • So using `guarding macros` is same as using `pragma once`? – Alxspb Jul 18 '17 at 19:03
  • Should I use forward declaration in B.h to make `A* parent` is compiling? – Alxspb Jul 18 '17 at 19:05
  • Names that begin with an underscore folloed by a capital letter (`_A_H_`) and names that contain two consecutive underscores are reserved for use by the implementation. Don't use them in your code. – Pete Becker Jul 18 '17 at 19:07
  • 2
    Include guards only address part of the problem here. The remaining issue is that class `A` uses `B*` and class `B` uses `A*`; that requires forward declarations. – Pete Becker Jul 18 '17 at 19:09
  • So, I should use forward declaration and just include both headers in source cpp file? – Alxspb Jul 18 '17 at 19:11
  • yes, in your case you would also need a forward declaration of `A` or `B` or both. – Serge Jul 18 '17 at 19:28
  • also the names of macro were used arbitrary, but they should include file name in a form to make them unique across the whole project. – Serge Jul 18 '17 at 19:29
1

Forward declare class A; in B.h and class B; in A.h

You should then move the implementation of onRemove() to B.cpp and include A.h here.

Also don't forget your include guards. Example:

#ifndef _A_H_
#define _A_H_

class B;

class A {

};

#endif

The include guards could also be replaced by #pragma once at the beginning of the header, this is a little less verbose.

Edit

To be complete:

// A.h

#pragma once

#include <vector>

class B;
class A {
    std::vector<B*> arr;

public:
    void Update(int32 id);        
};

// A.cpp

#include "A.h"

// possibly #include "B.h" if necessary

void A::Update(int32 id) {
    // impl ...
}

// B.h

#pragma once

class A;
class B
{
    int32 id;
    A* parent;

public:
    void OnRemove();
};

// B.cpp

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

void B::OnRemove() {
    parent->Update(id);
}

Well, something like this...

arjen1988
  • 109
  • 1
  • 5