Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 循环依赖修复_C++_Include_Circular Dependency - Fatal编程技术网

C++ 循环依赖修复

C++ 循环依赖修复,c++,include,circular-dependency,C++,Include,Circular Dependency,我确信这是我的设计缺陷,主要是因为我来自Java背景。但事实就是这样 以下是一般设置: 我有一个类,比如说a和#包括“B.h” 此外,我还有B类和#包括“C.h” 最后,我有一个类C,带有#包括“A.h” 我怎样才能解决这个问题?我尝试了一些与转发声明相关的业务,但它似乎不起作用,尽管我并不认为我做得对。可能是名称空间 我尝试了一些与远期声明有关的业务,但似乎不起作用 您没有向我们展示什么“似乎不起作用”,或者它以什么方式“似乎不起作用”,但代码中有一个地方可以用转发声明替换完整的类型定义,还有

我确信这是我的设计缺陷,主要是因为我来自Java背景。但事实就是这样

以下是一般设置:

我有一个类,比如说
a
#包括“B.h”

此外,我还有
B类
#包括“C.h”

最后,我有一个类
C
,带有
#包括“A.h”

我怎样才能解决这个问题?我尝试了一些与转发声明相关的业务,但它似乎不起作用,尽管我并不认为我做得对。可能是名称空间

我尝试了一些与远期声明有关的业务,但似乎不起作用

您没有向我们展示什么“似乎不起作用”,或者它以什么方式“似乎不起作用”,但代码中有一个地方可以用转发声明替换完整的类型定义,还有两个地方不能

你不能去的地方 非静态数据成员必须是完整类型:

[C++11:9.2/10]:
非静态的
(9.4)数据成员不能有不完整的类型。特别是,类
C
不应包含类
C
的非静态成员,但它可以包含指向类
C
对象的指针或引用

因此,不能向前声明
A
中的
B
B
中的
C::EnumType

顺便说一句:这不是
静态
数据成员的情况,数据成员可以向前声明:

[C++11:9.4.2/2]:
在其类定义中声明的
静态
数据成员不是定义,可能是除cv qualified
void
之外的不完整类型

你能去的地方 但是,成员函数声明中的参数类型并非如此,因此您可以在
C(a)
中向前声明
a

#在标题中尽可能少地包含

为什么你不需要这么做 我确信这是我的设计缺陷,主要是因为我来自Java背景

我不认为Java与之有任何关系,但是,是的,您的设计似乎有缺陷,因为这些类都相互依赖。也许
C::EnumType
应该改为
B::EnumType
?尽量使你的类更加独立。前向声明都很好,但如果解决了设计紧密耦合的根本问题,生活就会轻松得多

我尝试了一些与远期声明有关的业务,但似乎不起作用

您没有向我们展示什么“似乎不起作用”,或者它以什么方式“似乎不起作用”,但代码中有一个地方可以用转发声明替换完整的类型定义,还有两个地方不能

你不能去的地方 非静态数据成员必须是完整类型:

[C++11:9.2/10]:
非静态的
(9.4)数据成员不能有不完整的类型。特别是,类
C
不应包含类
C
的非静态成员,但它可以包含指向类
C
对象的指针或引用

因此,不能向前声明
A
中的
B
B
中的
C::EnumType

顺便说一句:这不是
静态
数据成员的情况,数据成员可以向前声明:

[C++11:9.4.2/2]:
在其类定义中声明的
静态
数据成员不是定义,可能是除cv qualified
void
之外的不完整类型

你能去的地方 但是,成员函数声明中的参数类型并非如此,因此您可以在
C(a)
中向前声明
a

#在标题中尽可能少地包含

为什么你不需要这么做 我确信这是我的设计缺陷,主要是因为我来自Java背景


我不认为Java与之有任何关系,但是,是的,您的设计似乎有缺陷,因为这些类都相互依赖。也许
C::EnumType
应该改为
B::EnumType
?尽量使你的类更加独立。正向声明都很好,但是如果你解决了设计紧密耦合的根本问题,生活就会简单得多。

@Lightness说了这一点-如果你使用“正向”定义声明类a,你不需要将a.h包含到C的编译单元中。只要写上“A级;”输入头,它告诉编译器(和链接器)在以后找出A是什么。唯一的缺点是文件C不再知道A的内部内容,因此必须使用引用或指针

另一种方法是将C分成两部分。是否有理由将枚举嵌入其中,而不是B的一部分?如果C和B共享枚举定义,则应将其拆分为一个单独的类,或者仅作为顶级枚举


当我得到这样的循环定义时,我会仔细检查我在做什么。我总是觉得我把事情弄得有点太复杂了。

@Lightness说了这一点——如果使用“forward”定义声明类a,就不需要在C的编译单元中包含a.h。只要写上“A级;”输入头,它告诉编译器(和链接器)在以后找出A是什么。唯一的缺点是文件C不再知道A的内部内容,因此必须使用引用或指针

另一种方法是将C分成两部分。是否有理由将枚举嵌入其中,而不是B的一部分?如果C和B共享枚举定义,则应将其拆分为一个单独的类,或者仅作为顶级枚举

当我得到这样的循环定义时,我会仔细检查我在做什么。我总是觉得我做的事情有点不对劲
#include "B.h"

class A {

    // stuff
private:
    B _b;

}
#include "C.h"

class B {

    // more stuff

private:
    C::EnumType _cEnum;
}
#include "A.h"

class C {
public:
    C(A a);
    enum EnumType {
        // enum stuff
    };

    // more stuff

}
class A;

class C {
public:
    C(A a);
    enum EnumType {
        // enum stuff
    };

    // more stuff
};
class A;

class C {
public:
    C(A a);
    enum EnumType {
        // enum stuff
    };

    // more stuff
};