Reputation: 37
I have two classes Screen and Window_Mgr(C++ Primer 5th Edition Chapter 7).
I want to write this code in such a way that only Window_Mgr::clear is a friend of Screen.
The problems I am faced with are:
I tried including them with separate header files but that was a real mess.
#include <iostream>
#include <vector>
class Screen;
struct Window_Mgr{
public:
// using Screen_Index = std::vector<Screen>::size_type;
typedef std::vector<Screen>::size_type Screen_Index;
void clear(Screen_Index i);
Window_Mgr() = default;
private:
std::vector<Screen> Screens;
};
struct Screen{
typedef std::string::size_type pos;
friend void Window_Mgr::clear(Screen_Index i);
Screen() = default;
Screen(pos h, pos w, char s): height(h), width(w), contents(h*w,s){};
char get() const { return contents[cursor];}
char get(pos ht, pos width)const;
Screen &move(pos r, pos c);
Screen &set(char);
Screen &set(pos, pos, char);
Screen & display(std::ostream &);
const Screen & display (std::ostream &) const;
pos size() const;
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
const Screen do_display (std::ostream& os) const
{
os << contents;
return *this;
}
};
Upvotes: 0
Views: 277
Reputation: 512
consider using classes instead and your forward declaration is for a class, where you create screen as a struct. This might be causing some of your issues. and instead of using a friend how about two separate clear functions one for Window_mgr that calls a different clear function in Screen.
your window_mgr clear would be something like
void Window_Mgr::clear(int i)
{
Screens.at(i).clear();
}
and your Screen clear would be something like
void Screen::clear()
{
//whatever you want to do to private variables here
}
And as one of my professors beat into our heads "Friends of classes are not friends of programmers"
Upvotes: 2
Reputation: 57698
You are violating encapsulation by having Screen
call Window_Mgr
.
The Window_Mgr
is a container of Screen
s. The Window_Mgr
should call the clear
method of a screen.
struct Screen
{
void clear()
{
//...
}
};
struct Window_Mgr
{
std::vector<Screen> Screen_Container;
void clear_screen(unsigned int screen_index)
{
Screen_Container[screen_index].clear();
}
};
Due to simplicity, I have not placed in checks for index ranges.
Edit 1: Friendship.
There is no need for friendship here. The Window_Mgr
can only access what the Screen
class has defined in its interface.
Also, the Screen
class should have no knowledge of whether it is in a container or not; that concept belongs to the Window_Mgr
class.
Upvotes: 1