我有一个循环引用的问题(即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:我忘了使用指针。我的实际程序确实使用了指针而不是普通的对象值而忽略了我急于创建一个小例子。
答案 0 :(得分:10)
你不能拥有循环依赖。
这样想。如果您实例化A类型的对象;那有多大?答案是无限大的。因此,无论如何都无法创建像这样的圆形对象。
您需要使用可选值(指针)来中断循环 SO如果你改变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
。
答案 1 :(得分:5)
不,#pragma once
不能解决循环依赖问题,只不过标准包含后卫。你正在做的本质上是一个递归结构,你不能使用普通值的递归结构,因为这意味着sizeof(T) == infinity
。这里的解决方案是:
std::unique_ptr
(或只是原始指针,如果它不拥有实例)而不是普通值来保存B
中的A
实例。反之亦然,取决于你的班级实际是什么。当然,最好的解决方案是在设计层面彻底摆脱循环依赖(重构常见的部分,那种东西)。
stdafx.h
无关(名称只是一个约定) - 搜索“预编译头”。