I've been trying some examples in a book (C++ Primer by Stanley Lippman) and I understand that a class can make another class its friend (to access some private members). Now I'm reading about a member function being a friend and I try the example
class Screen
{
public:
friend void Window_mgr::clear();
typedef std::string::size_type pos;
Screen () = default;
Screen (pos ht, pos wd, char c) : height (ht), width (wd),
contents (ht * wd, c) { }
private:
void do_display (std::ostream &os) const
{
os << contents;
}
pos cursor = 0;
pos height = 0, width = 0;
pos test_num = 100, test_num2 = 222;;
std::string contents = "contents";
};
class 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 = std::string(s.height * s.width, ' ');
}
but it produces a compiler error saying
Window_mgr has not been declared
and then I read this:
• First, define the Window_mgr class, which declares, but cannot define, clear. Screen must be declared before clear can use the members of Screen.
• Next, define class Screen, including a friend declaration for clear.
• Finally, define clear, which can now refer to the members in Screen.
I don't understand this part -- can someone explain?
You are most of the way there, you just need to ensure that you declare all of your classes and functions before you require that declaration.
The first instruction point says to define the
Window_mgr
class declaringWindow_mgr::clear
. In order to useScreen
, that class must also be declared beforeWindow_mgr
. This looks like:The second point says to define
Screen
and include a friend declaration forWindow_mgr::clear
. Because that member function has already been declared above, this is valid:The final point tells you to now define
Window_mgr::clear
. We have already declared in in the first point, so we just need to do this:When the compiler gets to
friend void Window_mgr::clear();
it has no idea whatWindow_mgr
is as it has not seen that yet. You need to reorder things around a little to get this to work. first you forward declareScreen
and then you have youWindow_mgr
Then you can have you
Screen
classAnd then you can have the parts of
Window_mgr
that useScreen
You can see it all working in this live example
One problem is that the signature of your
clear
methods differ. The one declared in theScreen
class takes an argument, and the other does not. Signatures must be identical, or the language actually sees them as different functions.A second problem is that your implementation conflicts with your first point: "define the
Window_mgr
class, which declares, but cannot define,clear
." YourWindow_mgr
class both declares and definesclear
.