0

間接化せずにヘッダーファイルでこれらのクラスを宣言する方法はありますか?

// Forwards declaration of B
class B;

class A
{
public:
    // Default parameter referring to B.  May return its parameter
    const B& func(const B& b = B());
};

class B
{
public:
    // B ctors
    B() {}
    B(const B&) {}

    // B has A as a member
    A a;
};

Visual C ++ 2008は、次のように教えてくれます。

error C2514: 'B' : class has no constructors

そして、Bの前方宣言(「クラスB;」)を指し、明らかに以下のBのコンストラクターを見ることができません。BにはメンバーとしてAが含まれているため、AはBをフォローできません。

間接参照を使用する必要がある場合、最善の方法は何ですか?おそらくC++0xではBのAはunique_ptrメンバーである可能性がありますか?それとも、純粋にこの問題を回避するためのブーストクラスがありますか?

4

1 に答える 1

7

デフォルトのパラメーターの代わりに、2つのオーバーロードを宣言します。1つはB参照によって取得し、もう1つはパラメーターを取得しません。パラメータをとらないものでは、もう一方をで呼び出します。B()これは、定義後にそのメソッドを定義できるため、機能しBます。

...
    void func();
    void func(const B& b);
};

class B...

void A::func() { func(B()); }
void A::func(const B&) { }

アップデート:

func()はconst B&..を返します。

それはおそらく良い考えではありません。その定義では、次のようなものです。

const B& foo = a.func();
foo.bar();

B最初のステートメントが完了するとすぐに参照先の参照が破棄されるため、恐ろしい「未定義動作」(つまり、クラッシュ)が発生します。クラスメンバー以外のものを参照によって返すことは、通常、悪い考えです。

本当にこれを実行したい場合は、呼び出し元に明示的に渡すように強制することに固執していると思います。これにB()はデフォルトのパラメーターがありません。

a.func(B()).bar();

(これは、このような関数で未定義の動作を回避する唯一の方法です。)

もちろん、参照の代わりにコピーを返すこともできますが、そうしない理由があると思います。

実行している内容によっては、参照の代わりにスマートポインターを使用して、より適切なセマンティクスを設定できる場合がshared_ptrあります。これにより、オブジェクトの存続期間を効果的に無視できます。ただし、代わりに参照サイクルに注意する必要があります。

これを何に使用しようとしているのかわかりませんが、いくつかのデザインパターンを調べて、確立されたベストプラクティスがあるかどうかを確認することをお勧めします。この小さな問題は、クラス構造または包含の不幸な選択の兆候であることがわかる場合があります。

于 2009-12-14T00:07:07.143 に答える