Reputation:
I have a simple movie database program I'm working on to learn C++.
I have a Main.cc file ...
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#include "MovieController.h"
int main()
{
MovieController mc;
mc.execute();
return 0;
}
... which creates and 'executes' a MovieController ...
#ifndef MOVIECONTROLLER_H
#define MOVIECONTROLLER_H
#include "MovieView.h"
class MovieController
{
public:
void execute();
void showMainMenuUI();
void doAddMovie(string title, int year, string genre);
private:
MovieView movieView;
};
#endif
... MovieController has a MovieView which is calls to show UI stuff ...
#ifndef MOVIEVIEW_H
#define MOVIEVIEW_H
#include "MovieController.h"
class MovieView
{
public:
void showMainMenu();
void showAddMovie();
private:
MovieController movieController;
};
#endif
... the MovieView has a MovieController so it can call back to the controller to add movies and so on.
My problem is when I compile Main.cc I get the following error ...
$ g++ -o test Main.cc
In file included from MovieController.h:4:0,
from Main.cc:17:
MovieView.h:17:5: error: ‘MovieController’ does not name a type
Why can't the MovieView recognize the MovieContoller type?
Upvotes: 0
Views: 50
Reputation: 510
Main includes MovieController MovieController includes MovieView MovieView attempts to include MovieController, but the ifndefs don't allow for it which is a good thing.
One of these two classes is conceptually inside of or owned by the other. Conceptually, a MovieController owns a MovieView, but a MovieView doesn't own a controller it just needs a reference back to it. MovieView needs to have a pointer so that it can reference the original MovieController, but it shouldn't have an actual MovieController or it would attempt to make it's own controller, seperate from the one that made it. That movie controller would make a new MovieView... which would make a new MovieController... which would make a new MovieView... etc... forever.
Upvotes: 1
Reputation: 308111
You have circular includes. The definition of MovieView
requires the definition of MovieConroller
, but the definition of MovieController
requires the definition of MovieView
.
Each .h
file includes its dependencies, but it's physically impossible for both definitions to come before the other. The include guard definitions determine which one wins.
You need to break it up so that one only requires a reference or pointer to the other, then do a forward declaration.
Upvotes: 4