1

我遇到了循环引用的问题(即 Ah 和 Bh #包括彼此),有些人建议我使用 #pragma 一次来防止这种情况。但是,此解决方案似乎仍然无法正常工作。

发生的情况是 A 类不再在 Ah 以外的任何文件中被识别(甚至在 A.cpp 中也不被识别),B 类也是如此。

让我给你看一下代码:

#pragma once
#include "B.h"

class A {
public: B* b;

};

溴化氢

#pragma once
#include "A.h"

class B {
    public: A* a;
};

A.cpp

#include "stdafx.h"
#include "A.h"
#include "B.h"

B.cpp与A.cpp相同

错误跟踪如下所示:

1> B.cpp 1>c:\users\user\documents\visual studio 2010\projects\envmodel\test\bh(5): 错误 C2143: 语法错误: 缺少';' 在 ' ' 1>c:\users\user\documents\visual studio 2010\projects\envmodel\test\bh(5) 之前:错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int 1>c:\users\user\documents\visual studio 2010\projects\envmodel\test\bh(5):错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int 1> A.cpp 1>c:\users\user\documents\visual studio 2010\projects\envmodel\test\bh(5): error C2143: syntax error: missing ';' 前 '' 1>c:\users\user\documents\visual studio 2010\projects\envmodel\test\bh(5):错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int 1>c:\users\user\documents\visual studio 2010\projects\envmodel\test\bh(5):错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数

还有两点我想澄清:

  1. 如何以及何时在 Visual Studio 2010 中使用 #include "stdafx.h"(我真的很讨厌这个 IDE,但它似乎是唯一一个与 C++ 兼容的 IDE——Netbeans 完全是这种语言的垃圾)

  2. 如何正确使用#pragma 一次?我假设我只是把它放在每个文件的第一行(好吧,显然这并不能解决我的问题!)。另外,它应该放在#include "stdafx.h" 之前还是之后?注意:我没有在 stdafx.h 中放置一次#pragma

谢谢。

编辑:我忘记了分号,因此原来的错误跟踪是臃肿的。Edit2:我忘了使用指针。我的实际程序确实使用了指针而不是普通的对象值,我在匆忙创建一个小例子时忽略了这一点。

4

2 回答 2

10

你不能有循环依赖。

像这样想。如果您实例化类型 A 的对象;那么它有多大?答案是无限大的。所以无论如何你都不能创建像那样的圆形对象。

您需要使用可选值(指针)来打破循环。
因此,如果您更改 B 以保存指向 A 的指针并使用前向引用,那么它就可以工作。

#pragma once
class A; // Forward reference.

class B {
    public: A* a; // Break cycle with a pointer. (In real life use a smart pointer)
}

注意:您仍然应该#pragma once在头文件中使用。

于 2012-06-06T16:34:35.497 回答
5

不,#pragma once不解决循环依赖问题,而不是标准包含保护。你所做的本质上是一个递归结构,你不能有一个使用普通值的递归结构,因为这意味着sizeof(T) == infinity. 这里的解决方案是:

  1. 不包括 Ah 中的 Bh
  2. 使用std::unique_ptr(或者只是一个原始指针,如果它不拥有实例)而不是普通值来保存B实例A

反之亦然,具体取决于您的课程实际上是什么。当然,最好的解决方案是在设计级别完全摆脱循环依赖(重构公共部分,诸如此类)。

stdafx.h不相关(名称只是一个约定)- 搜索“预编译头”。

于 2012-06-06T16:32:19.687 回答