3

次のコードがあるとします。

class Screen;

class WindowMgr
{
    WindowMgr& relocateScreen( int r, int c, Screen& s);
};

class Screen
{
    friend WindowMgr& WindowMgr::relocateScreen( int r, int c, Screen& s);
    // ^ cannot access private member declared in class 'WindowMgr'

    int m_nR,
        m_nC;
};

WindowMgr& WindowMgr::relocateScreen( int r, int c, Screen& s)
{
    s.m_nR = r;
    s.m_nC = c;
    return *this;
}

ScreenクラスがWindowMgr::relocateScreenメンバー関数をフレンドとして宣言できないのはなぜですか? 別のクラスのこのプライベート メンバー関数を使用するScreenのではなく、その関数が独自のプライベート メンバーにアクセスできるようにするだけです。

クラス内でのみ使用することを意図している場合、relocateScreen関数を公開することは悪い設計になる可能性があります。WindowMgr同様に、他の場合にのプライベート メンバーにアクセスすることが意図されていない場合Screen、 のフレンドを作成するWindowMgrことは悪い設計になる可能性があります。WindowMgr

ここでどこが間違っていますか?正しいアプローチは何ですか?私は自分を馬鹿にしていますか?

4

4 に答える 4

1

WindowMgr::relocateScreen()は に非公開であるため、フレンド宣言は機能しませんWindowMgr

C++ 標準 11.4-7:

「フレンド宣言によって指定された名前は、フレンド宣言を含むクラスのスコープ内でアクセス可能でなければなりません...」

個人的にはrelocateScreen()、プライベート メンバー関数をScreen作成WindowMgrし、friendofを作成しScreenます。そうすれば、 をWindowMgr呼び出すだけrelocateScreen()Screen、 のデータ メンバーに触れる必要がなくなりますScreen

于 2010-07-21T20:08:46.690 に答える
0

インシリコ-標準を引用するのに最適です。その上で眠った後、私は今、理論的根拠を理解しています:

WindowMgr::relocateScreenそのパラメータリストでの友達であると宣言することによりScreenScreenクラスはクラスのプライベート実装に依存するようになりWindowMgrます。これは、カプセル化/情報隠蔽に違反します。

OODの信条に違反しないために、クラスのパブリックメンバー関数のみが別のクラスのフレンドとして宣言できます。そうしないと、後者が前者のプライベート実装に依存するようになるためです。

于 2010-07-22T11:06:47.843 に答える
0

WindowMgrは、Screenをフレンドとして宣言する必要があります。前方宣言を使用できます。

于 2010-07-21T20:05:25.820 に答える
0

WindowMgr::relocateScreen を別のクラスに分解してみませんか。Delcare WindowMgrFoo は Screen in Screen の友人であり、WindowMgrFoo から非公開で WindowMgr を継承させますか? または、WindowMgr に WindowMgrFoo への参照を持たせますが、それを公開する場合は、ユーザーによる呼び出し方法を変更する必要があります。

于 2010-07-21T20:12:20.880 に答える