Domanda

I have two classes that depend on each other like this:

// model.h
#include "facet.h"
class Model {
    ...
    std::map<int, std::vector<Facet*> > enqueue_list_;
}

// facet.h
#include "model.h"
class Facet {
    ...
    Model *parent_;
}

The compiler is obviously very upset when trying to compile this. I have fixed it with forward class declarations like this:

// model.h
#include "facet.h"
class Facet;
class Model {
    ...
    std::map<int, std::vector<Facet*> > enqueue_list_;
}

// facet.h
#include "model.h"
class Model;
class Facet {
    ...
    Model *parent_;
}

But I'm not a fan of doing this. It seems messy and hard to maintain to me. I thought that this sort of problem is solved by using header files to begin with. Is there a better way to fix my problem that I'm missing? I'd love to not have to forward declare classes in other class header files. I feel like I'm missing something important here. What exactly is the point of header files if I still get cross dependency complaints?
Thanks in advance,
Max

Edit

Thanks for the quick responses. I took the advice and removed the includes in the header files and switched entirely to forward declarations. I am right to assume I still need to actually include the header if the class has a class allocation directly like this:

// facet.h
#include "point.h"
class Facet {
    ...
  private:
    Point normal_;
}

I was getting errors when trying to use a forward declaration here. Is this indeed a situation in which I must #include?

È stato utile?

Soluzione

You should not be #includeing at all. Since you only store pointers, you do not need the full definition of the classes - you only need the declaration. Simply use the forward declarations by themselves:

// model.h
class Facet;

class Model {
    ...
    std::map<int, std::vector<Facet*> > enqueue_list_;
}

// facet.h
class Model;

class Facet {
    ...
    Model *parent_;
}

The point of header files is to be able to reuse declarations of functions and objects and definitions of classes in multiple translation units. In this case, you don't need a definition of a class, only a declaration.

As you had it originally, model.h would include facet.h would include model.h would include facet.h... This clearly leads to an infinite recursive inclusion. If you had include guards on your headers, the infinite recursion would be prevented, but one of the classes would be left not knowing about the other. For example, if model.h is being preprocessed first, it will include facet.h and be able to see the definition of Facet, but then facet.h wouldn't be able to include model.h (because of the inclusion guard) and so it wouldn't know anything about Model.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top