0

I am following the book - C++ Primer for learning C++. I'm in middle of the chapter introducing classes, and I'm stuck in resolving the header files include of two classes taken as example there.

Here are the two classes, and the header files:

ScreenCls.h:

#ifndef SCREENCLS_H
#define SCREENCLS_H

#include <iostream>

#include "WindowManager.h"

using namespace std;

class ScreenCls {
    friend void WindowManager::clear(ScreenIndex);

public:
    typedef string::size_type pos;
    ScreenCls() { }
    ScreenCls(pos height, pos width, char c): height(height), width(width), contents(height * width, c) { }

    ScreenCls &set(char);
    ScreenCls &set(pos, pos, char);

    char get() const { return contents[cursor]; }  // Implicitly inline

private:
    pos cursor;
    pos height;
    pos width;
    string contents;
};

#endif // SCREENCLS_H

ScreenCls.cpp:

#include "ScreenCls.h"

char ScreenCls::get(pos r, pos c) const {
    pos row = r * width;
    return contents[row + c];
}

ScreenCls &ScreenCls::set(char ch) {
    contents[cursor] = ch;
    return *this;
}

ScreenCls &ScreenCls::set(pos r, pos c, char ch) {
    contents[r * width + c] = ch;
    return *this;
}

WindowManager.h:

#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H

#include <iostream>
#include <vector>
#include "ScreenCls.h"

using namespace std;

class WindowManager {

public:
    // location ID for each screen on window
    using ScreenIndex = vector<ScreenCls>::size_type;
    // reset the Screen at the given position to all blanks
    void clear(ScreenIndex);

private:
    vector<ScreenCls> screens{ Screen(24, 80, ' ') };
};

#endif // WINDOWMANAGER_H

WindowManager.cpp:

#include "WindowManager.h"
#include "ScreenCls.h"

void WindowManager::clear(ScreenIndex index) {
    ScreenCls &s = screens[i];
    s.contents = string(s.height * s.width, ' ');
}

This is my project structure:

/src/ScreenCls.cpp 
/src/WindowManager.cpp 
/include/ScreenCls.h 
/include/WindowManager.h

I'm using Code::Blocks IDE. I've added /src and /include folder in the Search Directory in the compiler Settings. I've also added the project root directory to the search directory.

Now, when I'm trying to build the project, it shows following errors:

'ScreenCls' was not declared in this scope (WindowManager.h)  
'ScreenIndex' has not been declared (WindowManager.h)  
'ScreenIndex' has not been declared (ScreenCls.h)  

And I've no idea what's happening here. I searched through some resources online, and found this link. And it's not helping here. Can someone take some time to look and suggest a solution?

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • 2
    [This should help](http://stackoverflow.com/questions/14909997/why-arent-my-include-guards-preventing-recursive-inclusion-and-multiple-symbol) (first of the two Q&A) – Andy Prowl May 14 '13 at 15:48
  • have you tried calling the class through its folder anyway? e.g. `#include "include/WindowManager.h"` – Syntactic Fructose May 14 '13 at 15:51

1 Answers1

1

It's simple:

Your program #includes "ScreenCls.h" which in turn includes "WindowManager.h". But the #include of "ScreenCls.h" in "WindowManager.h" does nothing because it has already been included and now WindowManager.h does not know what ScreenCls is.

You need a forward declaration instead which means you either declare as much of your class as necessary or use pointers.

Sarien
  • 6,647
  • 6
  • 35
  • 55
  • I added a forward declaration : `class ScreenCls;` before the `WindowManager` class in the `WindowManager.h`. Now it cannot find `WindowManager` in `ScreenCls`. :( – Rohit Jain May 14 '13 at 16:05
  • Hm...okay...I assume another forward declaration would help but I have to admit, I am confused as well. :) – Sarien May 14 '13 at 16:09
  • Ah! Done with Building. Had to remove forward declaration from WindowManager header, and include the class rather. And in .cpp file, had to just include the class. Need to understand the logic badly. Thanks :) – Rohit Jain May 14 '13 at 16:12
  • Ah, that is probably the compilation of WindowManager.cpp. There you included WindowManager.h which would in turn include ScreenCls.h which now misses the definition of WindowManager. There, all good. ;) – Sarien May 14 '13 at 16:14
  • You usually shouldn't include the .cpp file. It sometimes makes sense but "It's wrong." is a good rule of thumb. (To be honest I can't even think of a case where it does make sense.) – Sarien May 14 '13 at 16:15