我试着理解C ++中的编译/链接是如何工作的。所以我创建了一个简单的测试项目,它具有以下形式:
A.H
class A {
public:
int a;
A() { a = 3; }
};
B.h
#include "A.h"
class B {
private:
A myA;
};
Main.cpp的
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main() {
A myA;
B myB;
cout << myA.a;
}
如果我尝试编译这个,我得到一个C2011(类类型重新定义)。这对我来说很清楚,因为B.h也包括A.h,而我的Main会看起来像:
class A { ...} // through include of A.h in Main.cpp
class A { ...}
// through include of B.h in Main.cpp which includes A.h as.
// well causes the redefinition error
int main() { ... }
但为什么也是C2079错误
'B::myA' uses undefined class 'A'
在B.h?因此,如果我包含A.h,则应插入A的类定义,B.h应该看起来像
class A { ... }
class B {
private:
A myA;
};
为什么A类没有在B.h中定义?应该通过包括A.h来提供类(如果我在Main.cpp中删除了A.h的包含它没有问题)
答案 0 :(得分:0)
主要包括A和B. B包括A =&gt;主要包括A两次。使用ifndef
。其中_UNIQ_FILE_NAME_
为A_H
,B_H
为
#ifndef _UNIQ_FILE_NAME_
#define _UNIQ_FILE_NAME_
// Content here
#endif // _UNIQ_FILE_NAME_
答案 1 :(得分:0)
如果我尝试编译这个,我得到一个C2011(类类型重新定义)。这对我来说很明显,因为B.h也包括A.h
所以,如果你清楚为什么你有错误,为什么不修复它?通常您应该使用header guards来确保它们只包含一次:
if let fontUsage = font.fontDescriptor.fontAttributes["NSCTFontUIUsageAttribute"] as? String {
if fontUsage == "CTFontHeavyUsage" {
print("It's Heavy")
}
else if fontUsage == "CTFontBlackUsage" {
print("It's Black")
}
}
但为什么还有C2079错误
#ifndef A_h_ #define A_h_ class A { public: int a; A() { a = 3; } }; #endif /* A_h_ */
正如你所指出的那样,没有标题保护你的'B::myA' uses undefined class 'A'
看起来像这样:
Main.cpp
这显然是一个错误,因为你定义了两个相同的类A.从这一点来看,其余的编译是没有意义的,因为Main.cpp不会编译,但编译器可能会忽略与{相关的错误} {1}}并尝试编译文件的其余部分以显示任何其他可能的错误。因为class A { ... }
class A { ... }
class B { ... }
...
有两个定义,所以它无法知道哪一个是正确的,因此微软编译器可能会将剩余的编译视为没有定义class A
。这就是你获得class A
的原因。
gcc for example won't report errors与使用class A
有关,只会告诉您有'B::myA' uses undefined class 'A'
并会显示之前定义的位置。
答案 2 :(得分:0)
要回答实际问题&#34;但为什么[还有] C2079错误B::myA
使用未定义的类A
&#34; :
编译器通常会尝试提供帮助并一次检测多个错误。为此,他们必须对第一个错误的性质做出一些假设。这可能并不总是很好,这似乎是其中一个案例。
即使A
被标记为有问题,编译器仍继续编译,然后因使用A
事后看来,错误可能更好,因为&#34;&#39; B :: myA&#39;使用多重定义的类&#39; A&#39;&#34;。