我有一个循环引用的问题(即A.h和B.h #including each),有些人建议我使用#pragma一次来防止这种情况 . 但是,此解决方案似乎仍然无效 .
发生的事情是A类不再在A.h以外的任何文件中被识别(即使在A.cpp中也没有),B类也是如此 .
我来告诉你代码:
A.h
#pragma once
#include "B.h"
class A {
public: B* b;
};
B.h
#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 \ b.h(5):错误C2143:语法错误:缺少';'在''1>之前c:\ users \ user \ documents \ visual studio 2010 \ projects \ envmodel \ test \ b.h(5):错误C4430:缺少类型说明符 - 假定为int . 注意:C不支持default-int 1> c:\ users \ user \ documents \ visual studio 2010 \ projects \ envmodel \ test \ b.h(5):错误C4430:缺少类型说明符 - 假定为int . 注意:C不支持default-int 1> A.cpp 1> c:\ users \ user \ documents \ visual studio 2010 \ projects \ envmodel \ test \ b.h(5):错误C2143:语法错误:缺少';'在''1>之前c:\ users \ user \ documents \ visual studio 2010 \ projects \ envmodel \ test \ b.h(5):错误C4430:缺少类型说明符 - 假定为int . 注意:C不支持default-int 1> c:\ users \ user \ documents \ visual studio 2010 \ projects \ envmodel \ test \ b.h(5):错误C4430:缺少类型说明符 - 假定为int . 注意:C不支持default-int
还有两件事我想澄清一下:
-
如何以及何时在Visual Studio 2010中使用#include“stdafx.h”(我真的很讨厌这个IDE,但它似乎是唯一适用于C - Netbeans的用这种语言的完全垃圾)
-
如何正确使用#pragma?我假设我只是把它放在每个文件的第一行(好吧,显然这不能解决我的问题!) . 是否应该在#include“stdafx.h”之前或之后放置?注意:我没有在stdafx.h中输入#pragma一次
谢谢 .
编辑:我忘记了分号,因此原始错误跟踪变得臃肿 . Edit2:我忘了使用指针 . 我的实际程序确实使用指针而不是普通的对象值,我忽略了我急于创建一个小例子 .
2 回答
您不能拥有循环依赖项 .
可以这样想 . 如果您实例化A类型的对象;那有多大?答案是无限大的 . 因此,您无法创建像这样的圆形对象 .
您需要使用可选值(指针)来中断循环 .
因此,如果您更改B以保持指向A并使用前向引用,则它可以正常工作 .
注意:您仍应在头文件中使用
#pragma once
.不,
#pragma once
不会解决循环依赖问题,只不过标准包括后卫 . 你所做的实际上是一个递归结构,你不能使用普通值来 Build 递归结构,因为这意味着sizeof(T) == infinity
. 这里的解决方案是:在A.h.中不包括B.h.
使用
std::unique_ptr
(或只是一个原始指针,如果它不拥有实例)而不是普通值来保存A
中的B
实例 .反之亦然,取决于您的课程实际是什么 . 当然,最好的解决方案是在设计层面完全摆脱循环依赖(重构常见的部分,那种东西) .
stdafx.h
是无关的(名称只是一个约定) - 搜索"precompiled header" .