2

重複の可能性:
ネストされた C++ クラスと列挙を使用することの長所と短所?

次の宣言を検討してください。

class A {
    public:
    class B{
    };
};

特にない。

  • しかし、これの利点は何ですか?
  • あるクラスを別のクラスに入れる理由は何ですか?
  • 両方のクラス間に継承の利点はありません。
  • プライベートな名前を共有するために B が A の内部に置かれている場合、A は B にとって単なる名前空間であり、B をプライベートにする理由もあります。

これについてあなたはどう思いますか?

4

3 に答える 3

4

概念的には、クラス B が特にクラス A に関連していることをプログラマーに知らせます。クラス A の外でクラス B を使用する場合は、型を A::B として使用する必要があります。これは機能を追加しませんが、関係を示しています。

同様に、継承/構成、またはクラスをまったく使用する必要はありません。構造体と関数を使用するだけで、C のクラスを多かれ少なかれシミュレートできます。これは、コードをよりクリーンで単純なものに保ち、プログラマーがコードをデザインに簡単に関連付けられるようにするための方法にすぎません。クラスは、パブリック サブクラスよりもはるかに多くのことを実現しますが、これは単なる例です。

それがプライベート/保護されたサブクラスである場合(これはあなたの例にはありません)、それは明らかにそのクラスをそのクラスの実装とそのクラスの子に制限します。そのクラスのユースケースは、そのクラス(およびおそらくその子)の実装にあります。

于 2012-11-06T07:50:05.893 に答える
1

利点 1: 名前空間の側面

実際、Aは の名前空間を提供しますB。これは、コードをより適切に構造化するのに役立ちます。vectorfor A、およびiteratorforを使用した具体的な例を考えてみましょうB。おそらく、

class vector {
public:
  class iterator { /*...*/ };

  iterator begin() { /*...*/ }
};

よりも入力しやすく、読みやすく、理解しやすい

class vector_iterator {
  /*...*/
};

class vector {
public:
  vector_iterator begin() { /*...*/ }
};

特に次の点に注意してください。

  1. 2 つのクラス (vectoriterator) が互いに依存している場合、つまり互いのメンバーを使用している場合、上記の 2 番目のバージョンでは、2 つのうちの 1 つを前方宣言する必要があり、場合によっては相互の型依存関係によって解決できない状況が発生する可能性があります。(ネストされたクラスを使用すると、ネストされたクラス定義のほとんどの部分で、外側のクラスが完全に定義されていると見なされるため、このような問題を回避するのがはるかに簡単になります。これは §9.2/2 によるものです。)

  2. 独自のデータ型を維持する他の多くのデータ型を持っている可能性がありiteratorますlinked_list。上記の 2 番目のバージョンを使用するlinked_list_iteratorと、別のクラスとして定義する必要があります。クラス名は、これらの「依存」タイプと代替タイプを追加すると、ますます長く複雑になります。

利点 2: テンプレート

上記の例を続けて、コンテナー (上で定義したvectorおよびなど) を引数として取り、それらを反復処理する関数テンプレートを考えてみましょう。linked_list

template <typename Container>
void iterate(const Container &container) {
  /*...*/
}

この関数内では、 の反復子型を使用したいと思うことは明らかですContainer。それがネストされた型である場合、それは簡単です:

typename Container::iterator

しかし、そうでない場合は、反復子の型を別のテンプレート パラメーターとして取得する必要があります。

template <typename Container, typename Iterator>
void iterate(const Container &container) {
  /*...*/
  Iterator it = container.begin();
  /*...*/
}

そして、その反復子の型が関数の引数に現れない場合、コンパイラは型を推測することさえできませんでした。関数を呼び出すたびに、山かっこで明示的に追加する必要がありiterateます。

最終的な注意:これは、ネストされたクラスが public または private として宣言されているかどうかとはあまり関係がありません。上記の例は、入れ子になった public 型が明らかに好ましい状況を示唆しています。なぜなら、そのiterator型はコンテナー クラスの外で使用できるはずだからです。

于 2012-11-06T08:18:39.613 に答える
0

あるクラスを別のクラスの中に入れる理由は何ですか?

  • B のスコープを A でのみ使用できるように制限する必要がある場合は、内部クラス定義が役立ちます。クラスのスコープをローカルに制限するためです。これは呼び出しスコープのローカライゼーションinner class declarationです。このリンクを確認してください。
  • このスタックオーバーフローの質問は、理解を深めるのに役立ちます。
于 2012-11-06T07:53:24.087 に答える