1

循環依存関係のトピックをたくさん読みましたが、問題を解決するトピックが見つかりませんでした。相互へのポインタを含む2つのクラスがあります。

class B;

class A
{
public:
    A(B* _b, int _c): b(_b), c(_c) {}
    B* b;
    int c;
};

class B
{
public:
    B(A* _a, int _d): a(_a), d(_d) {}
    A* a;
    int d;
};

問題は、次のコードにあることです。

class C
{ 
public:
    A* a_ptr;
    B* b_ptr;
    C() 
    {
        a_ptr = new A(b_ptr, 3);
        b_ptr = new B(a_ptr, 2);
        qDebug() << a_ptr->c;
        qDebug() << b_ptr->d;
        qDebug() << a_ptr->b->d;
        qDebug() << b_ptr->a->c;
    }
}

最後の2行はアプリケーションをクラッシュさせています。問題とクラッシュの理由を理解しています。メンバーのセッターを作成し、オブジェクトの作成後に呼び出すことができるので、ポインターは有効になります。ただし、他のメソッドを呼び出さずに、コンストラクターを呼び出した後にオブジェクトを完成させたいと思います。

だから...コンストラクターに(循環)ポインターを挿入する方法があるかどうか疑問に思っていましたか?

4

1 に答える 1

2

1人のコンストラクターに他のオブジェクトの初期化を完了させることができます。

B(A* a_ptr) : a(a_ptr)
{
    if(a)
        a->b = this;
}

そして、同じですA()。したがって、次のように作成できます。

a_ptr = new A(b_ptr, 3); // b_ptr was initialized to 0
b_ptr = new B(a_ptr, 2); // b_ptr->a = a_ptr
                         // b_ptr->a->b = b_ptr (ie, a_ptr->b = b_ptr)

編集:コメントで述べられているように、クラスがたくさんある場合、これはスケーラブルではありません。ただし、一般的なケースでは、コンストラクターの外部で循環依存関係を初期化する必要があります。次に、相互に循環依存するクラスをたくさん持つべきではありません(その場合は、コードを再配置できます... )。

于 2013-03-24T12:36:37.110 に答える