如何分两个文件写友元成员函数
在C++ primer(第五版)一书中,讲到友元函数的时候,对于友元成员函数的使用做了如下声明:
1.首先定义Window_mgr类,其中声明了clear函数,但是不能定义它。在clear使用Screen的成员之前必须先声明Screen。
2.接下来定义Screen,包括对于clear的友元声明。
3.最后定义clear,此时它才可以使用Screen的成员。
原书练习7.32的方法
遵循上面的定义,书中练习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 void Window_mgr::clear(ScreenIndex);
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
inline void Window_mgr::clear(ScreenIndex i)
{
if (i >= screens.size()) return; // judge for out_of_range.
Screen &s = screens[i];
s.contents = std::string(s.height * s.width, ' ');
}
这个代码遵循了最开始的三个原则,在定义Window_mgr之前声明了Screen,这个声明称为前向声明,这是一种不完全类型,他的作用是只能用于函数的声明里面的参数或返回类型,以及指向此类型的指针或引用,但不能切实的在一个函数定义中使用这种不完全类型,因此在Window_mgr里面就只有clear函数的声明而已。之后定义Screen,并在Screen里面声明Window_mgr里面的clear函数为友元成员函数。clear函数的定义则在Screen类的下面定义,在这里也就可以真正的使用Screen类了。
把两个类放到不同的文件
以上是一种很好的方案,但是如果要把Screen类和Window_mgr类放在不同的文件怎么办呢?
先建一个文件Window_mgr.h,里面的内容如下
class Screen;
class Window_mgr {
public:
using ScreenIndex = std::vector<Screen>::size_type;
void clear(ScreenIndex index);
private:
std::vector<Screen> screens;
};
Screen.h里面的内容如下
#include "Window_mgr.h"
class Screen {
friend void Window_mgr::clear(std::vector<Screen>::size_type index);
public:
typedef std::string::size_type pos;
private:
mutable size_t access_ctr;
pos cursor = 0; //光标位置
pos width = 0, height = 0; //所在位置的高和宽
std::string contents; //所显示的内容
};
void Window_mgr::clear(ScreenIndex index)
{
Screen &s = screens[index];
s.contents = std::string(s.width * s.height, ' ');
}
此处不能只是引入Window_mgr的不完全类型,而应该include进来,否则会报错误,因为此处的Window_mgr不只是用于函数的参数和指针或引用。而且发现clear函数必须写在Screen里面,因为它只能在Screen定义后才能定义。
由此,有一点疑问,是否有友元成员函数关系的两个类的标准写法就是写在一个文件里面呢?不明所以,特此标出,以后再解答。