2008-08-02 24 views
40

私は、ビデオの再生と録音に使用されるクラスのコレクションについて取り組んでいます。 play()stop()pause()record()などのメソッドを使用して、パブリックインターフェイスのように動作する1つのメインクラスを持っています。次に、ビデオデコードとビデオエンコードを行うワークホースクラスがあります。この場合、ネストされたクラスを使用する必要がありますか?

C++でネストされたクラスの存在について知りましたが、プログラマがそれらを使用することについてどのように考えているのか不思議です。私は少し慎重で、利点/欠点が何であるかを本当に確信していませんが、私のようなケースで使用されるように見えます(私が読んでいる本によると)。

本書では、私のようなシナリオでは、インターフェイスクラスの中にワークホースクラスをネストするのが良い解決策であると考えているので、クライアントが使用するクラス以外のファイルはありません。名前の競合?私はこれらの正当化について知らない。ネストされたクラスは新しい概念です。プログラマーがその問題について何を考えているかを見たいだけです。

答えて

24

ここでネストされたクラスを使用するのは少し嫌です。バックエンドのもの(仕事場)を処理するための「マルチメディアドライバ」の抽象基本クラスを作成し、フロントエンド作業用の別のクラスを作成したらどうでしょうか?フロントエンドクラスは、実装されたドライバクラスへのポインタ/参照を(適切なメディアタイプと状況のために)取ることができ、要点構造に対して抽象オペレーションを実行することができる。

私の哲学は、両方の構造を洗練された方法でクライアントにアクセスできるようにすることです。ちょうどそれらが並んで使用されるという前提の下にあります。

QtでQTextDocumentのようなものを参照します。ベアメタルのデータ処理に直接のインタフェースを提供しますが、QTextEditのようなオブジェクトに権限を渡して操作を行います。

4

ネストされたクラスを使用するかどうかを決定する1つの方法は、このクラスがサポートする役割を果たしているのか、それとも自分の部分であるのかを考えることです。

他のクラスを助けるためだけに存在する場合は、通常、それをネストされたクラスにします。それには注意が必要ですが、その中には矛盾しているように見えるものもありますが、それはすべて経験と嫌悪感に満ちています。

3

を使用することができます場合は、時にはそれがユーザーから実装クラスを非表示にする適切だように聞こえる - これらの場合には、パブリッククラス定義の内部よりもfoo_internal.hに入れた方がよいでしょう。そうすれば、あなたのfoo.hの読者はあなたが悩まされたくないものを見ていないでしょうが、インタフェースの具体的な実装のそれぞれに対してテストを書くことができます。

8

メインクラスを実装するために必要な(小さな)ヘルパークラスを作成するには、ネストされたクラスを使用します。あるいは、例えば、インタフェース(抽象メソッドを持つクラス)を定義する。

この場合、ネストされたクラスの主な欠点は、再利用が難しくなることです。おそらく、別のプロジェクトでVideoDecoderクラスを使用したいと思うかもしれません。 VideoPlayerのネストされたクラスにする場合、これをエレガントな方法で行うことはできません。

代わりに、別のクラスを別々の.h/.cppファイルに入れて、VideoPlayerクラスで使用できます。 VideoPlayerのクライアントは、VideoPlayerを宣言しているファイルをインクルードするだけで、実装方法をまだ知る必要はありません。

1

外部クラスのpublicインターフェイスを使用して別のクラスとして実装できない場合にのみ、内部クラスを使用する必要があります。内部クラスは、クラスのサイズ、複雑さ、および責任を増加させるため、控えめに使用する必要があります。それは、より良いフィットするようにあなたが今まで他の言語で使用するためにSWIG(http://www.swig.org)でコードをラップする場合

あなたのエンコーダ/デコーダクラスが鳴り、ネストされたクラスを避けるためにStrategy Pattern

0

一つの理由です。 Swigは現在ネストされたクラスに問題があります。したがって、ネストされたクラスを公開するライブラリとのインタフェースは本当の苦痛になります。

3

準古いSun C++コンパイラと、標準で動作が変更されたネストされたクラスの可視性に問題がありました。もちろん、古いコンパイラを含む多くのプラットフォームでソフトウェアをコンパイルする予定がある場合は、ネストされたクラスをやりなおす理由ではありません。

0

あなたの仕事関数(デコードやエンコーディングなど)の実装方法を想像してみてください。その場合、関数を実装する異なる具象クラスを持つ抽象基本クラスが必要になります。実際の実装の種類ごとに別々のサブクラスをネストすることは実際には適切ではありません。

4

あなたのInterfaceクラスのあなたの仕事場のクラスへのポインタを使用し、インターフェイスメソッドのパラメータや戻り値の型として公開していない場合は、その作業馬の定義をインターフェイスヘッダーに含める必要はありませんファイル(代わりにそれらを宣言するだけです)。そうすれば、インタフェースのユーザーはバックグラウンドでクラスについて知る必要はありません。

このためにクラスをネストする必要はありません。実際には、クラスファイルが別々になっているため、プロジェクトが成長するにつれて、コードをより読みやすく、管理しやすくなります。サブクラス化する必要がある場合は、後で助けになります(異なるコンテンツ/コーデックタイプについて言う)。

PIMPL pattern(セクション3.1.1)の詳細はこちらです。

関連する問題