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

主文件

#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 继承的,所以你必须#include A3.h

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,你需要在其中包含所有内容:

主文件

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

int main(){
    int i;
}

希望有帮助!这是对前向声明以及何时/如何使用它的快速参考。

编辑:感谢 Pablo 指出我的错误。您不能将前向声明的类用作成员对象,只能使用引用或指针。我已将上述示例更改为使用指针。

于 2011-12-10T02:15:07.040 回答
0

我的建议:使用更多的指针和尽可能多的前向声明(并避免#include .h 文件中的其他头文件。#include 它们在需要实现的 .cpp 文件中。)

所以

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

您不能将不完整的类型声明为成员。

您将在此问题的第二个答案中找到一些有用的信息

于 2011-12-10T03:39:27.363 回答