Круговая помощь зависимостей в C ++ - PullRequest
0 голосов
/ 10 декабря 2011

У меня есть код, подобный следующему, но я не могу понять, как заставить его работать.

Я искал его и, похоже, что-то про циклическую зависимость, но сейчас яя пробовал с некоторыми примерами, но работаю только с зависимостью 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;
}

Буду очень признателен, если кто-то сможет помочьмне исправить код, чтобы он мог работать.

Ответы [ 2 ]

1 голос
/ 10 декабря 2011

Для CtrlA.h, CtrlB.h, A1.h и A3.h вам не нужно ничего включать ):

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, куда вы захотите включить их все:

main.cpp

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

int main(){
    int i;
}

Надеюсь, это поможет! Вот краткий справочник для пересылки декларации и когда / как ее использовать.

Редактировать: Спасибо Пабло за указание на мою ошибку. Вы не можете использовать объявленные заранее классы в качестве объектов-членов, только ссылки или указатели. Я изменил приведенные выше примеры, чтобы использовать указатели.

0 голосов
/ 10 декабря 2011

Мой совет: используйте больше указателей и как можно больше прямых объявлений (и избегайте # включения других заголовков в файлы .h.требуется реализация.)

Итак

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

Нельзя объявить неполный тип как член.1015 * Немного полезной информации, которую вы найдете во 2-м ответе на этот вопрос

...