6

C++ Primer 5th Edition から演習 7.32 を実行しようとしています。その演習では、次のことが求められます。

独自のバージョンのScreenWindow_mgrを定義し、clearは のメンバーでWindow_mgrあり、 のフレンドですScreen

以下は 、 の定義でScreenありWindow_mgrclear本文に記載されています。

class Screen
{
  public:
    using pos = std::string::size_type;
    Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) { }
  private:
    pos height = 0, width = 0;
    std::string 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, ' ');
}

これらの 2 つのクラスは、Window_mgr よりも最初に Screen を定義すると、期待どおりに動作します。ここで、この演習ではclear、Screen のフレンドを作成して を定義するように求められますclear。メンバーをclear友達にするには、私の理解が正しけれWindow_mgrば、定義する必要があります。を定義するにはWindow_mgr、を定義するScreen必要があります。これは私には不可能に思えます。

テキストは次のヒントを提供します。

メンバー関数を友達にするには、プログラムを慎重に構造化して、宣言と定義の間の相互依存性に対応する必要があります。この例では、プログラムを次のように順序付ける必要があります。

  • まず、Window_mgrを宣言するが定義しないクラスを定義しますclear。のメンバーを使用するScreen前に宣言する必要があります。clearScreen

  • 次に、Screenのフレンド宣言を含むclass を定義しますclear

  • 最後に、clearのメンバーを参照できるようになった を定義しますScreen

この演習を解決しようとした順序は、最終的に次のとおりです。

class Screen;

class Window_mgr
{
  public:
    using ScreenIndex = std::vector<Screen>::size_type;
    void clear(ScreenIndex);
  private:
    std::vector<Screen> screens{Screen(24, 80 ' ')};
};

class Screen
{
  friend Window_mgr::clear(Window_mgr::ScreenIndex);
  public:
    using pos = std::string::size_type;
    Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) { }
  private:
    pos height = 0, width = 0;
    std::string contents;
};

void Window_mgr::clear(ScreenIndex i)
{
  Screen &s = screens[i];
  s.contents = std::string(s.height * s.width, ' ');
}

ベクトルは完全な型でWindow_mgrある必要があるため、これは明らかに機能しません。これは、作成者が以前に提示したクラスScreenを使用するつもりがない限り、解決できない演習のように思えます。ScreenWindow_mgr

他の誰かが C++ Primer からこの演習を解決しましたか? もしそうなら、どのように?これをどのように行うことができるか、または私の腸が私に言うように、何か助けはありませんか?

4

1 に答える 1