0

我有两个类 Screen 和 Window_Mgr(C++ Primer 第 5 版第 7 章)。

  1. Screen 是一个包含三个string::size_types和一个字符串作为数据成员的类。
  2. Window_Mgr 是一个包含向量< Screen >类型的对象Screens的类。
  3. 它使用 Screen 中的构造函数使用值(24,80,' ')初始化向量< Screen >
  4. void Window_Mgr::clear(vector::size_type i)是一个访问字符串私有成员并清除它们所有数据的函数。

我想以只有 Window_Mgr::clear 是 Screen 的朋友的方式编写此代码。

我面临的问题是:

  1. 如果我在 Screen 之前使用不完整的声明定义 Window_Mgr ,我将无法初始化Screens
  2. 如果我在 Window_Mgr 之前用不完整的声明定义 Screen ,我不能将Window_Mgr::clear声明为Screen的朋友。

我尝试将它们包含在单独的头文件中,但那真是一团糟。

#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;
    }
};
4

2 回答 2

2

考虑改用类,并且您的前向声明是针对一个类,您可以在其中将屏幕创建为结构。这可能会导致您的一些问题。与其使用朋友,不如使用两个单独的清除函数,一个用于 Window_mgr,它在 Screen 中调用不同的清除函数。

您的 window_mgr clear 将类似于

void Window_Mgr::clear(int i)
{
    Screens.at(i).clear();
}

你的屏幕清晰将类似于

void Screen::clear()
{
    //whatever you want to do to private variables here
}

正如我的一位教授在我们脑海中敲响的那样:“课堂之友不是程序员之友”

于 2013-11-09T19:02:50.533 回答
1

你有Screencall违反了封装Window_Mgr

Window_Mgr是 s 的容器ScreenWindow_Mgr应该调用屏幕的方法clear

struct Screen
{
  void clear()
  {
     //...
  }
};


struct Window_Mgr
{
  std::vector<Screen> Screen_Container;
  void clear_screen(unsigned int screen_index)
  {
    Screen_Container[screen_index].clear();
  }
};

由于简单,我没有检查索引范围。

编辑1:友谊。
这里不需要友谊。Window_Mgr只能访问Screen类在其接口中定义的 内容。

此外,Screen该类应该不知道它是否在容器中;该概念属于Window_Mgr该类。

于 2013-11-09T19:20:14.593 回答