#include <string>
#include<iostream>
#include<vector>
//test 7.32
class Screen;
class Window_mgr
{
public:
using ScreenIndex = std::vector<Screen>::size_type;
inline void clear(ScreenIndex);
private:
std::vector<Screen> screens;
};
class Screen
{
friend class Window_mgr;
//friend void Window_mgr::clear(ScreenIndex);
public:
using pos = std::string::size_type;
Screen() = default;
Screen(pos ht, pos wd) :height(ht), width(wd), contents(ht*wd, ' '){}
Screen(pos ht, pos wd,char c) :height(ht), width(wd), contents(ht*wd, c){};
char get()const { return contents[cursor]; }
char get(pos r, pos c)const { return contents[r*width + c]; }
inline Screen& move(pos r, pos c);
inline Screen& set(char c);
inline Screen& set(pos r, pos c, char ch);
const Screen& display(std::ostream &os)const
{
do_display(os);
return *this;
}
Screen& display(std::ostream &os)
{
do_display(os);
return *this;
}
private:
void do_display(std::ostream &os)const
{
os << contents;
}
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
inline void Window_mgr::clear(ScreenIndex i)
{
if (i >= screens.size()) return;
Screen &s = screens[i];
s.contents = std::string(s.height*s.width, ' ');
}
inline Screen& Screen::move(pos r, pos c)
{
cursor = r*width + c;
return *this;
}
inline Screen& Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
inline Screen& Screen::set(pos r,pos c,char ch)
{
contents[r*width + c] = ch;
return *this;
}
在这段代码中,只有
friend class Window_mgr;
这个类友元,这句:s.contents = std::string(s.height*s.width, ' ');
才不会有红线标出。
如果将下面这个成员函数友元,不友元类,inline函数内的上面这句则会有红线,显示
friend void Window_mgr::clear(ScreenIndex);
请问这是为什么呢?我是找github上的答案敲的,把他的拷到编译器里面也会出现这个错误。
In fact, it is an error caused by classes referencing each other. .
There is no problem in declaring Window_mgr alone as a member of Screen, but if you use member functions, you will find the definition of the class, and your Window_mgr also contains members of Screen, so the compiler will be confused. I think It may also be an implementation problem, although the same is true for the gcc I use. .
I found that the following code will not compile at all
But it can be compiled and passed as a template parameter. It is probably because vector actually uses pointers. .
You can use pointers to get rid of this mutual reference problem
Single ~~ Window_mgr
AsFriend ~~ Screen
single.h
single.cpp
friend.h
friend.cpp
test
There is no problem with the program. You can make the member functions of the class a separate friend, so that only the member function has access privileges to the declared object (Screen).
A method of a separate friend class must meet three conditions. In the example here:
The Window_mgr class must be defined first. It must be declared in the class definition, but cannot be defined. The clear method function
Define the Screen class, including the friend declaration for Window_mgr::clear
Finally Window_mgr::clear can be defined, and the function can provide privileged access to Screen
This is the original text of C++ Primer. I have tested it with VS2013 and it can be compiled and passed.
As for this problem, at first I thought it was due to inline, but later experiments revealed that it was not.
Now I can only think that it is a problem with IntelliSense in VS2013. After all, this writing method is rare, and the intelligent sensing assistant has not yet learned this method of friending a certain class function.
If you have the opportunity, you can experiment in VS2015 or other IDEs.
The subject's code was compiled and passed under VS2015, with no problems (using member function friends), and there was no error message in the screenshot. It may be that the IntelliSence cache of the subject VS is not refreshed.