Thread: Including header in order

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    114

    Including header in order

    Hi.. I have two classes in two different order.. The classes are
    Code:
    #ifndef SCREEN_H_INCLUDED
    #define SCREEN_H_INCLUDED
    class Screen;
    class Window_mgr;
    class Screen{
    friend void Window_mgr::clear(ScreenIndex);
    friend void showscreen(const Screen&);
    friend istream &read(istream&,Screen&);
    public:
       typedef string::size_type pos;
       Screen()=default;
       Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c){}
       char get() const {return contents[cursor];}
       inline char get(pos ht,pos wd) const;
       Screen &move(pos r,pos c);
       void some_member() const;
       Screen &set(char);
       Screen &set(pos,pos,char);
    
    private:
        mutable size_t access_ctr;
        pos cursor=0;
        pos height=0,width=0;
        string contents;
    };
    
    inline
    Screen &Screen::move(pos r,pos c)
    {
        pos row=r*width;
        cursor =row+c;
        return *this;
    }
    char Screen::get(pos r,pos c) const
    {
        pos row=width*r;
        return contents[row+c];
    }
    void Screen::some_member() const
    {
        ++access_ctr;
    }
    void showscreen(const Screen &in)
    {
        for(unsigned i=0;i<in.height*in.width;++i)
    {
        if(i&&i%in.width==0) cout<<endl;
        cout<<in.contents[i];
    }
    cout<<endl;
    }
    istream &read(istream &is,Screen &in)
    {
        cout<<"Enter the height,width and character of the screen seperated by space "<<endl;
        is>>in.height>>in.width;
        char c=getwchar();
        string s(in.height*in.width,c);
        in.contents=s;
        return is;
    }
    inline Screen &Screen::set(char c)
    {
        contents[cursor]=c;
        return *this;
    }
    inline Screen &Screen::set(pos r,pos col,char c)
    {
        contents[r*width+col]=c;
        return *this;
    }
    #endif // SCREEN_H_INCLUDED
    and
    Code:
    #ifndef WINDOW_MGR_H_INCLUDED
    #define WINDOW_MGR_H_INCLUDED
    class Screen;
    class Window_mgr;
    struct Window_mgr{
    
    public:
        using ScreenIndex=std::vector<Screen>::size_type;
        void clear(ScreenIndex);
    private:
        std::vector<Screen> screens{Screen(24,80,' ')};
    
    };
    
    void Window_mgr::clear(ScreenIndex i)
    {
    Screen &s=screens[i];
    s.contents=string(s.width*s.height,' ');
    }
    
    #endif // WINDOW_MGR_H_INCLUDED
    I want to make only clear function of Window_mgr as friend.. It is not compiling. Which order should I include.
    may main file is
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    #include "Screen.h"
    #include "Window_mgr.h"
    
    
    
    
    
    int main()
    {
    
    Screen sc;
    read(cin,sc);
    sc.set(1,3,'D');
    sc.move(4,0).set('#');
    showscreen(sc);
    }

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Window depends on screen, so window's header file should actually include screen.h ...

    I don't think anything else should be done. This would allow clients to include window and screen in any order.

  3. #3
    Registered User
    Join Date
    Jan 2013
    Posts
    114
    That gives the compiler error..
    I have changed the class screen 1st lines into this
    Code:
    Code:
    class Screen{
    friend void Window_mgr::clear();
    and in in windowsclass Screen; class Window_mgr; #include "Screen.h" struct Window_mgr{ public:
    The errors are, at line 6.
    Invalid use of Incomplete type 'class Window_mgr' and and ScreenIndex has not been declared and another error is forward declaration of class Window_mgr,.

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Guess from a C Programmer.

    Did you try using class instead of struct?

    Code:
    struct Window_mgr{
    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If class Screen needs to declare Window_mgr::clear() as a friend, the compiler needs to see the definition of the Window_mgr before the definition of the Screen class. Always.


    There are other problems in your code that would cause compilations errors, such as the Window_mgr class using std::vector, despite the <vector> header never having been #include'd.


    Quote Originally Posted by stahta01 View Post
    Guess from a C Programmer.

    Did you try using class instead of struct?
    Nothing to do with it. A class and a struct are equivalent in C++, except for different default access (private versus public) and inheritance.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    Jan 2013
    Posts
    114
    but if I show the definition of Window_mgr, than Window_mgr gives the error.. cause I have used Screen in that too.. So theres is no way to do what am I trying to do aye?.

  7. #7
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Just #indclude "screen.h" in "window_mgr.h" and get rid of the useless forward declarations of Screen and Window_mgr.
    Kurt

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Don't put non-inline methods loose in your header file. That will cause linking errors later on as your program grows and you need to include header files within multiple cpp files.
    Move them into .cpp files instead.

    Always copy and paste the errors you are getting here.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User
    Join Date
    Jan 2013
    Posts
    114
    Firstly.. I am using codeblocks! I tried to put the functions in cpp files... but I get huge number of errors heres my program when the files are transfered into .cpp file, my new files are like this
    main
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    #include "Window_mgr.h"
    
    int main()
    {
    
    Screen::pos ht=24,wd=10;
    Screen scr(24,10,' ');
    Screen *p=&scr;
    char c=scr.get();
    c=p->get();
    
    }
    Screen
    Code:
    #ifndef SCREEN_H_INCLUDED
    #define SCREEN_H_INCLUDED
    #include <iostream>
    
    
    class Screen{
        friend ostream& storeOn(std::ostream&,Screen&);
    friend class Window_mgr;
    friend void showscreen(const Screen&);
    friend istream &read(istream&,Screen&);
    public:
       typedef string::size_type pos;
       Screen()=default;
       Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c){}
       char get() const {return contents[cursor];}
       inline char get(pos ht,pos wd) const;
       Screen &move(pos r,pos c);
       void some_member() const;
       Screen &set(char);
       Screen &set(pos,pos,char);
       pos size() const;
    
    private:
        mutable size_t access_ctr;
        pos cursor=0;
        pos height=0,width=0;
        string contents;
    };
    
    #endif // SCREEN_H_INCLUDED
    Window_mgr
    Code:
    #ifndef WINDOW_MGR_H_INCLUDED
    #define WINDOW_MGR_H_INCLUDED
    #include <iostream>
    #include "Screen.h"
    #include <vector>
    struct Window_mgr{
    
    public:
        using ScreenIndex=std::vector<Screen>::size_type;
        void clear(ScreenIndex);
        ScreenIndex addScreen(const Screen&);
    private:
        std::vector<Screen> screens{Screen(24,80,' ')};
    
    
    };
    
    void Window_mgr::clear(ScreenIndex i)
    {
    Screen &s=screens[i];
    s.contents=string(s.width*s.height,' ');
    }
    Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen &s)
    {
        screens.push_back(s);
        return screens.size()-1;
    
    
    }
    #endif // WINDOW_MGR_H_INCLUDED
    and the functions of Screen in
    Code:
    Screen::pos Screen::size() const
    {
        return height*width;
    }
    inline
    Screen &Screen::move(pos r,pos c)
    {
        pos row=r*width;
        cursor =row+c;
        return *this;
    }
    char Screen::get(pos r,pos c) const
    {
        pos row=width*r;
        return contents[row+c];
    }
    void Screen::some_member() const
    {
        ++access_ctr;
    }
    void showscreen(const Screen &in)
    {
        for(unsigned i=0;i<in.height*in.width;++i)
    {
        if(i&&i%in.width==0) cout<<endl;
        cout<<in.contents[i];
    }
    cout<<endl;
    }
    istream &read(istream &is,Screen &in)
    {
        cout<<"Enter the height,width and character of the screen seperated by space "<<endl;
        is>>in.height>>in.width;
        char c=getwchar();
        string s(in.height*in.width,c);
        in.contents=s;
        return is;
    }
    inline Screen &Screen::set(char c)
    {
        contents[cursor]=c;
        return *this;
    }
    inline Screen &Screen::set(pos r,pos col,char c)
    {
        contents[r*width+col]=c;
        return *this;
    }
    This program gives several error Including ostream doesnt name a type,Istream doesnt name a type , string doesnt name a type etc etc.. and
    Always copy and paste the errors you are getting here.
    how to copy paste errors in code blocks?? When I right click on the error button theres no options such as copy..

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tamim Ad Dari
    This program gives several error Including ostream doesnt name a type,Istream doesnt name a type , string doesnt name a type etc etc.
    Take them one by one. For example, look at this line in your header:
    Code:
        friend ostream& storeOn(std::ostream&,Screen&);
    On one hand, you correctly qualified ostream to be std::ostream. On the other hand, you didn't. You made this kind of omission several times in your code.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jan 2013
    Posts
    114
    Thanks.. that helped.. But still When I declare clear as friend
    Code:
    friend void Window_mgr::clear();
    compiler gives the error that Window_mgr has not been declared.. so I used a forward declaration of class Window_mgr
    Code:
    class Window_mgr;
    It seems that code blocks dont support forward declaration of classes, because then it gives this more error
    Invalid use of incomplete type class Window_mgr, and error: forward declaration of Wondow_mgr..

  12. #12
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Tamim Ad Dari View Post
    Invalid use of incomplete type class Window_mgr, and error: forward declaration of Wondow_mgr..
    Looks loke you still haven't #included Window_mgr.h in Screen.h.
    Screen doesn't use Window_mgr so you do not need any forward declarations of Screen or Window_mgr at all.
    Kurt

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by Tamim Ad Dari View Post
    It seems that code blocks dont support forward declaration of classes, because then it gives this more error
    Invalid use of incomplete type class Window_mgr, and error: forward declaration of Wondow_mgr..
    FYI: Code::Blocks is NOT a Compiler; You need to learn the name of your Compiler; not the name of your IDE.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Tamim Ad Dari View Post
    But still When I declare clear as friend
    Code:
    friend void Window_mgr::clear();
    compiler gives the error that Window_mgr has not been declared.. so I used a forward declaration of class Window_mgr
    That is insufficient. To accept a declaration of Window_mgr::clear() as a friend, the compiler needs to have already encountered a definition of the class Window_mgr (not just a forward declaration).

    Quote Originally Posted by Tamim Ad Dari View Post
    Code:
    class Window_mgr;
    It seems that code blocks dont support forward declaration of classes, because then it gives this more error
    Invalid use of incomplete type class Window_mgr, and error: forward declaration of Wondow_mgr..
    Your conclusion is flawed, and the compiler is correct. A forward declaration of a class is not sufficient if your intent is to declare a member function as a friend.

    The compiler is telling you this in its own way: the compiler sees Window_mgr as an incomplete type if it has only been given a declaration. If you then use Window_mgr in a context where its complete class definition is needed, the compiler will complain - since it hasn't seen the class definition - about an incomplete type.


    You therefore need to be very careful about the order in which declarations and definitions appear. That is particularly true when there is dependency between two (or more) header files. Class declarations can be used to prevent those dependencies becoming circular. However, the catch is that sometimes the compiler requires a definition. It is then your responsibility to ensure, at every point in both header files, that the compiler has seen a definition when it needs it - regardless of the order in which the two (or more) header files happen to have been #include'd by other source files.

    The problem you're having is because you are ignoring that responsibility, and expecting the compiler to work things out anyway.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    All of that and it doesn't seem as if you listened to iMalc. (See the constructor for example.)

    Also, mixing and matching "namespace" aliases with `typedef' and similar other oddities makes me think you have "copypasta'd" this code into existence.

    That sort of thing will not work long term.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Including header
    By Tamim Ad Dari in forum C++ Programming
    Replies: 2
    Last Post: 02-22-2013, 02:27 AM
  2. Header Files / Including
    By FlamingAhura in forum C Programming
    Replies: 2
    Last Post: 11-03-2010, 09:03 PM
  3. including header file
    By Delia in forum C Programming
    Replies: 1
    Last Post: 03-20-2010, 04:52 PM
  4. Including my own header files
    By bushymark in forum C Programming
    Replies: 17
    Last Post: 11-03-2009, 09:09 PM
  5. Including header files
    By Emeighty in forum C++ Programming
    Replies: 5
    Last Post: 08-09-2008, 03:02 PM