2

操作中に別のクラス(クラスB)のインスタンスをいくつか作成できる必要があるクラス(クラスA)を構築していますが、クラスBはクラスAのいくつかのメンバー関数によってのみ使用されます。クラスの外で使用されることはありません。クラスBはどのように定義するのが最適ですか?クラスAのプライベートメンバーにすることは実用的/合理的ですか?これはネストされたクラスの意図された目的ですか、それとも私は構成の精神を手放していますか?

ありがとう、ワイアット

編集:これは個人的なプロジェクトのためのものであるため、さらに検討すると、私は実際にはベストプラクティスについて質問していません。カプセル化の観点から、クラスBをクラスAのメンバーとして含めたいと思います。完全に従属しているクラスが、実際にはそれ自体のクラスの一部であることが合理的であるように思われます。

私が疑問に思っているのは、これがネストされたクラスの妥当なユースケースであるかどうかです。そうでない場合、ネストされたクラスの目的は何ですか?

4

6 に答える 6

3

1 つのdetail可能性は、クラスを配置する名前空間内で呼び出される名前空間を定義することです。例えば

// public_namespace_detail.hpp
namespace public_namespace
{
    namespace detail
    {
        class B
        {
          ...
        };

    }
}

// public_namespace.hpp
#include "public_namespace_detail.hpp"

namespace public_namespace
{
    class A
    {
       detail::B b;
       ...       
    };
}
于 2010-12-20T15:52:00.587 に答える
2

私はclass B完全に無関係にします-他に何もないとしても、テストと個別class Aにテストできれば、テストの作成が簡単になります。そのルートに行きたくない場合は、を定義し、プライベートコンストラクターを作成してから、を作成する以外は、誰もインスタンス化できないようにします。class Aclass Bclass Bclass Aclass Bclass Afriend

于 2010-12-20T15:48:10.527 に答える
1

複数のオプションがあります:

  1. プライベート継承:class A : private B {};

  2. ネストされたクラス:class A { class B { /* etc */ }; };

  3. クラスAからクラスBへの古き良きプライベートメンバー:class A { B b; };

ネストされたクラスが外部で必要ないと100%確信している場合、私は個人的にネストされたクラスを使用します。

于 2010-12-20T15:51:28.347 に答える
0

私の一般的な経験則は、継承に関して難しい問題があることに気付いた場合、おそらく問題を間違った方法で見たということです。

クラスが「結合」されないようにプログラムを再構築する方法はありますか?IEクラスBを参照する関数をクラスAから移動できますか(そしてそれらをBに配置できますか)?

于 2010-12-20T15:48:50.537 に答える
0

そうしないと、Aのヘッダーファイルを介して他のクラスに公開されるため(好きかどうかに関係なく)、Bの外に移動します。つまり、B の実装を変更した場合、A のクライアントは再コンパイルする必要があります。B は A の内部で宣言されているためです。

私のプロジェクトの構造は、B のヘッダー ファイルが他のクラスで使用されるべきではないことを明確にする必要があります。たとえば、プロジェクト外で共有する予定のすべてのヘッダー ファイルを配置する「exports」というフォルダーがあります。明らかに、B のヘッダーはそこにはありません。

C# などのヘッダー ファイルを使用しない別の言語では、B がかなり小さい (おそらく 6 ~ 10 行の宣言を超えない) 場合、B を A の中にさりげなく配置します。

于 2010-12-20T15:58:48.173 に答える
0

はい、ここではネストされたクラスで問題ありません。

Bコードを整理するために、 insideの定義を配置しないことに注意してくださいA。その代わり:

class A
{
    class B;
};

class A::B
{
};

とりわけ、これにより、クラスの定義をA::BA の実装ファイル内に配置できます。

編集:ネストされたクラスが含まれているクラスのプライベートメンバーにアクセスできるかどうかについて混乱があるように見えるので、それを証明するコードスニペットを提供します:

class A
{
    int x;

    class B
    {
        int func(A* p) { return p->x; }
    };
};

のインライン定義のないバリアントA::Bも受け入れられます:

class A
{
    int x;

    class B;
};

class A::B
{
    int func(A* p) { return p->x; }
};
  • コモー: 承認済み (両方のバリアント)

Comeau C/C++ テストの結果は次のとおりです。

Comeau C/C++ 4.3.10.1 (2008 年 10 月 6 日 11:28:09) ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. 全著作権所有。MODE:厳密なエラー C++ noC++0x_extensions

厳密モードでは、-tused を使用すると、コンパイルは成功しました (ただし、Comeau オンライン コンパイラはリンクしないことに注意してください)。C++0x 拡張機能を無効にしてコンパイル。

于 2010-12-20T16:26:31.357 に答える