C++ C+中存在循环依赖时包含的固定顺序+;模板类

C++ C+中存在循环依赖时包含的固定顺序+;模板类,c++,circular-dependency,C++,Circular Dependency,我遇到了一个循环依赖性问题,其中头的包含顺序很重要。问题是类似的,但它并没有记录一个类实例化另一个类的对象的解决方案 问题: 我有两门课:Foo和Bar。酒吧是模板化的。(Foo可以模板化,也可以不模板化) Foo有一个Bar实例,Bar有一个Foo类型的指针,Bar的实现需要通过这个指针访问Foo的成员 Foo和Bar必须在单独的文件中实现。由于Bar是模板化的,它的声明和实现必须在同一个文件中 在下面的代码中,如果main.cpp在Foo.h之前包含Bar.h,那么代码将编译,而当Foo

我遇到了一个循环依赖性问题,其中头的包含顺序很重要。问题是类似的,但它并没有记录一个类实例化另一个类的对象的解决方案

问题:

  • 我有两门课:Foo和Bar。酒吧是模板化的。(Foo可以模板化,也可以不模板化)
  • Foo有一个Bar实例,Bar有一个Foo类型的指针,Bar的实现需要通过这个指针访问Foo的成员
  • Foo和Bar必须在单独的文件中实现。由于Bar是模板化的,它的声明和实现必须在同一个文件中
在下面的代码中,如果main.cpp在Foo.h之前包含Bar.h,那么代码将编译,而当Foo.h在Bar.h之前包含时,代码不会编译。是否有一种方法可以使代码编译,而不考虑main.cpp中包含头的顺序

Foo.h

#ifndef FOO_H
#define FOO_H

#include"Bar.h"
class Foo
{
    public:
        Bar<> B;
        void fooStuff(){};

};
#endif
#ifndef BAR_H
#define BAR_H

class Foo;
template<int N=0> class Bar
{
    public:
        Foo * F;
        void barStuff();
};

#include"Foo.h"
 template<int N> void Bar<N>::barStuff()
{
        F->fooStuff();
};
#endif
#include"Bar.h"

#ifndef FOO_H
#define FOO_H


class Foo
{
    public:
        Bar<> B;
        void fooStuff(){};

};
#endif
#ifndef BAR_H
#define BAR_H

class Foo;
template<int N=0> class Bar
{
    public:
        Foo * F;
        void barStuff();
};

#include"Foo.h"
 template<int N> void Bar<N>::barStuff()
{
        F->fooStuff();
};
#endif

是:在
Bar
之前声明
Foo
,因为
Bar
只使用指针,不需要完整定义。然后在
Bar
之后定义
Foo
——它使用一个对象,因此它确实需要定义

class Foo;

template<int N> class Bar
{
    public:
        Foo * M;
        void barStuff();
};

class Foo
{
    public:
        Bar<42> B;
        void fooStuff(){}
};

template<int N> void Bar<N>::barStuff()
{
    M->fooStuff();
}
Foo类;
模板类栏
{
公众:
Foo*M;
void barStuff();
};
福班
{
公众:
B栏;
void fooStuff(){}
};
模板空栏::barStuff()
{
M->fooStuff();
}

一般来说,对于需要类的任何属性(如大小或成员)的任何内容,您都需要完整定义,并且在声明函数、指针或引用时只需要声明使用类名。

我需要在Foo之前包含Bar,无论它们在main.cpp中以何种顺序包含。以下黑客似乎有效:

在Foo.h中,将Bar.h包括在收割台护罩外部。由于酒吧也有标题保护,它不会被包括多次

Foo.h

#ifndef FOO_H
#define FOO_H

#include"Bar.h"
class Foo
{
    public:
        Bar<> B;
        void fooStuff(){};

};
#endif
#ifndef BAR_H
#define BAR_H

class Foo;
template<int N=0> class Bar
{
    public:
        Foo * F;
        void barStuff();
};

#include"Foo.h"
 template<int N> void Bar<N>::barStuff()
{
        F->fooStuff();
};
#endif
#include"Bar.h"

#ifndef FOO_H
#define FOO_H


class Foo
{
    public:
        Bar<> B;
        void fooStuff(){};

};
#endif
#ifndef BAR_H
#define BAR_H

class Foo;
template<int N=0> class Bar
{
    public:
        Foo * F;
        void barStuff();
};

#include"Foo.h"
 template<int N> void Bar<N>::barStuff()
{
        F->fooStuff();
};
#endif

实际上,我很确定,这只是一个空洞的声明,完全合法的C++。另一个注意事项(尽管OP的代码中也存在此错误)是,他似乎对模板参数
Bar
所采用的内容有些困惑,并且缺少一些专门化。@DeadMG:你说得对;出于某种原因,我认为空声明是非法的,但事实并非如此。这一定是我C时代的宿醉。Foo和Bar需要在不同的文件中。对不起,我应该在前面加上那个具体的例子。