0

次のようなコードがありますが、それを機能させる方法がわかりません。

私はそれを検索し、循環依存関係のように見えますが、今のところ、いくつかの例を試してみましたが、依存関係 2 でのみ機能します。

代わりに、これには、多くのクラスが依存している「Ctrl」クラスがあります(CtrlAとCtrlBは相互に依存しており、Axクラスには両方のCtrlが必要です)が、これらのクラスの一部にはCtrlファイルも必要です(CtrlAにはAxが必要です)クラス)。また、継承されたクラスがあります (A2 は A3 を継承します)。

CtrlA.h

#ifndef CTRLA
#define CTRLA
#include "CtrlB.h"
#include "A1.h"

class CtrlB;
class A1;

class CtrlA{
    protected:
        A1 x;
    public:
        void op1(CtrlB b){
            a.op1(this, b);
        }
        void op2(){}
};
#endif

CtrlB.h

#ifndef CTRLB
#define CTRLB
#include "CtrlA.h"

class CtrlA;

class CtrlB{
    protected:
    public:
        void op1(){}
        void op2(CtrlA a){
            a.op1(this);
        }
};
#endif

A1.h

#ifndef A1
#define A1
#include "CtrlA.h"
#include "CtrlB.h"
#include "A2.h"

class CtrlA;
class CtrlB;

class A1{
    protected:
        A2 x1;
    public:
        void op1(CtrlA a, CtrlB b){
            x1.op1(this, b);
        }
};
#endif

A2.h

#ifndef A2
#define A2
#include "CtrlA.h"
#include "CtrlB.h"
#include "A3.h"

class CtrlA;
class CtrlB;

class A2:public A3{
    protected:

    public:
        void op1(CtrlA a, CtrlB b){
            a.op2();
            b.op1();
        }
};
#endif

A3.h

#ifndef A3
#define A3
#include "CtrlA.h"
#include "CtrlB.h"

class CtrlA;
class CtrlB;

class A3{
    protected:

    public:
        virtual void op1(CtrlA a, CtrlB b) = 0;
};
#endif

main.cpp

#include "CtrlA.h"
#include "CtrlB.h"

int main(){
    int i;
}

コードが機能するように誰かがコードを修正するのを手伝ってくれたら、とても感謝しています。

4

2 に答える 2

1

CtrlA.h、CtrlB.h、A1.h、および A3.h の場合、前方宣言を使用し (そうでした)、参照またはポインターを使用する場合 (そうではありませんでした)、何も #include する必要はありません。

CtrlA.h

#ifndef CTRLA
#define CTRLA

class CtrlB;
class A1;

class CtrlA {
    protected:
        A1* x; 
    public:
        /* Use a CtrlB reference instead -- probably wanted to do this anyway  
        /* since you don't want to copy CtrlB when called */
        void op1(CtrlB& b); /* Move function body to .cpp file */
        void op2(){}
};
#endif

A1.h

#ifndef A1
#define A1

class CtrlA;
class CtrlB;
class A2; /* You have to use forward declaration on every class you use below */

class A1{
    protected:
        A2* x1;
    public:
        void op1(CtrlA& a, CtrlB& b); /* Again, use references and move function 
                                         bodies to .cpp */
};
#endif

しかし、A2.h では A3 から継承しているため、A3.h を #include する必要があります。

A2.h

#ifndef A2
#define A2
#include "A3.h"

class CtrlA;
class CtrlB;

class A2:public A3{
    protected:

    public:
        void op1(CtrlA& a, CtrlB& b);
};
#endif

そして、main.cpp が残ります。ここにすべてを含めます。

main.cpp

#include "CtrlA.h"
#include "CtrlB.h"
#include "A1.h"
#include "A2.h"
#include "A3.h"

int main(){
    int i;
}

それが役立つことを願っています! これは、前方宣言とそれをいつ/どのように使用するかについてのクイックリファレンスです。

編集:私のエラーを指摘してくれたパブロに感謝します。前方宣言されたクラスをメンバー オブジェクトとして使用することはできません。参照またはポインターのみを使用できます。上記の例をポインターを使用するように変更しました。

于 2011-12-10T02:15:07.040 に答える
0

私のアドバイス:より多くのポインターとできるだけ多くの前方宣言を使用してください(.hファイルに他のヘッダーを#includeしないでください。実装が必要な.cppファイルにそれらを#includeしてください。)

そう

CtrlA.h

#ifndef CTRLA
#define CTRLA
//#include "CtrlB.h"//no, don't #include this here, use fwd decl below
//#include "A1.h"   //no

class CtrlB; // yes, use forward decl ONLY as much as possible
class A1;    // yes

// the only reason you'd NEED to have an #include is
// if CtrlA INHERITED CtrlB. Then you'd need to #include "CtrlB.h"

class CtrlA{
    protected:
        A1 *x; // make PTR, meaning you can live off
               // the fwd declaration in the header file
               // (but will need to #include "A1.h" in
               //  the .cpp file to use member functions of A1)
    public:
        void op1(CtrlB *b) ; // CtrlB ptr, NO IMPLEMENTATION HERE, put in .cpp
        void op2() ; // no impl
};
#endif

不完全な型をメンバーとして宣言することはできません。

この質問に対する 2 番目の回答にある役立つ情報

于 2011-12-10T03:39:27.363 に答える