3

公開する必要があるC ++のネストされたクラスがあります。しかし、そのメソッドの一部を外界から見えるようにし、残りのメソッドを入れ子クラスだけから見えるようにする必要があります。あれは:

class set {
public:
    class iterator {
        innerMethod();
    public:
        outerMethod();
    }
}

innerMethod() を使用する set のメソッドを記述できるようにしたいと考えています。公開すると外部からもアクセスできてしまうので、これは絶対に嫌です。「フレンドクラス設定」をせずにやる方法はありますか?

前もって感謝します!

4

5 に答える 5

2

friendキーワードを使用せずにこれを行う良い方法はありません。

あなたが言ったコメントで:

私が現在受講しているプログラミングのクラスでは、'friend' を使用することは賢明ではないと言われており、他に方法がない場合を除き、ほとんどの場合「悪いプログラミング」と見なされていました。だからなるべく避けるようにしています。

friendカプセル化を破ります。おそらくそれが、クラスの先生がプログラミングが悪いと言った理由です。しかし、メンバー関数もカプセル化を破ります。では、なぜそれらを使用するのでしょうか? それらも避けてみませんか?friendメンバー関数と同じ方法でカプセル化を解除します。したがって、必要なときにメンバー関数を快適に使用できる場合は、必要なときにfriendも快適に使用できるはずです。どちらも C++ に存在するのには理由があります。

class set {
public:
 class iterator 
 {
  friend class set; //<---- this gives your class set to access to inner methods!

  void innerMethod(){}
 public:
  void outerMethod(){}
 };
 iterator it;

 void fun()
 {
  it.innerMethod();
  it.outerMethod();
 }
};

これを参照してください:非メンバー関数がカプセル化を改善する方法

于 2011-01-13T12:34:27.850 に答える
1

はいあります。

私はしばらくの間この方法を提唱しようとしてきましたが、基本的な考え方はKeyクラスを使用することです。

これによって の使用が実際になくなるfriendわけではありませんが、公開されている一連の実装の詳細が削減されます。

class set;

// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };

class set
{

  // 2. Define the iterator
  class iterator
  {
  public:
    void public_method();

    void restricted_method(set_key&);

  }; // class iterator

}; // class set

現在restricted_methodは公開されているため、setへの特別なアクセスは必要ありませんiterator。ただし、その使用はインスタンスを渡すことができる人に制限されていset_keyます...そして便利なことにset、そのようなオブジェクトを構築することしかできません。

Note that set may actually pass a set_key object to someone else it trusts. It is a key in the traditional sense: if you give a key of your flat to someone, it may entrust it to another person. However because of the semantics of the key class (non copyable, only set may construct and destroy it) this is normally limited to the duration of the scope of the key object.

Note that a evil hack is always possible, namely *((set_key*)0). This scheme protects from Murphy, not Machiavelli (it's impossible in C++ anyway).

于 2011-01-13T14:24:08.620 に答える
1

いいえ、ハック以外の方法はないと思いますが、 - ディレクティブを使用しfriendます。

friendこの種の目的のために存在するのに、なぜそれを避けるのですか?

于 2011-01-13T12:28:05.467 に答える
1

質問してみてください: 2 つの数字を加算せずに加算する方法はありますか? 辛口で申し訳ありませんが、フレンドクラスはまさにそのためのものです...

于 2011-01-13T12:33:06.153 に答える
0

次のようなことができます。

クラスセット

{

public:
    class iterator
    {
        protected:
            iterator(){};
            virtual ~iterator(){};

        public:
            //outer world methods...
    };

private:
    class privateIterator : public iterator
    {
        public:
            privateIterator(){};
            ~privateIterator(){}

        //inner methods;
    };

public:
    iterator* CreateIterator()
    {
        return new privateIterator();//this is used to be sure that you only create private iterator instances
    }

};

それが正しい答えかどうかはわかりませんが、現在はフレンド キー ワークを使用し、いくつかのメソッドを非表示にしています。唯一の問題は、privateIterator を宣言できず、常に CreateIterator を使用してインスタンスを作成する必要があることです...

于 2011-01-13T12:51:01.267 に答える