소스 파일에서 클래스에 대한 포인터를 선언하거나 정의하려는 경우 클래스를 사용하기 전에 선언하거나 정의해야 하므로 다음 코드는 오류를 보고합니다.
class A
{
public:
B *b;
};
class B
{
public:
A *a;
};
int main()
{
return 0;
}
오류는 클래스 A에서 B *b를 사용하기 전에 클래스 B의 선언 또는 정의가 없기 때문에 "오류: 'B'는 유형의 이름을 지정하지 않습니다"입니다. 전방 선언(전방 선언)을 추가하면 "클래스 B;" , 그런 문제는 없을 것입니다.
헤더 파일이 서로 포함되어 있는 경우에도 "error: 'xxx' does not name a type"이 발생합니다. 오류 발생 원인은 위의 코드와 동일합니다. 다음 코드를 참조하십시오. ah
:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
#include "b.h"
class A
{
public:
B *b;
};
#endif // A_H_INCLUDED
bh:
#ifndef B_H_INCLUDED
#define B_H_INCLUDED
#include "a.h"
class B
{
public:
A *a;
};
#endif // B_H_INCLUDED
메인.cpp:
#include "a.h"
#include "b.h"
int main()
{
return 0;
}
컴파일이 오류를 보고합니다: "오류: 'A'는 유형의 이름을 지정하지 않습니다.", 왜 이런 일이 발생합니까? 전처리 후 ah가 무엇을 확장하는지 봅시다 전처리 명령은 "gcc -E -o ai ah"입니다.
# 1 "a.h"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.h"
# 1 "b.h" 1
# 1 "a.h" 1
# 5 "b.h" 2
class B
{
public:
A *a;
};
# 5 "a.h" 2
class A
{
public:
B *b;
};
"#"으로 시작하는 줄을 무시하고 지금은 처음에 소스 파일과 거의 동일하지만 클래스의 순서가 바뀌었으므로 오류 원인은 소스 파일과 동일하다는 것을 알았습니다. 시작.
해결책도 매우 간단합니다. ah의 "#include "bh""를 클래스 B의 사전 선언 "class B;"로 교체하고 bh에서 유사한 수정을 수행합니다. 그렇게 하면 문제가 발생하지 않습니다. 물론 이를 위해서는 전제 조건이 있는데, A 클래스의 멤버는 B 클래스에 대한 포인터만 가질 뿐 B 클래스의 변수는 가질 수 없으며 동시에 헤더 파일에서 B 클래스의 멤버 또는 멤버 함수에 액세스할 수 없습니다. 클래스 A의 두 경우 모두 클래스 A는 클래스 B의 크기 또는 기타 세부 정보를 알아야 하며 전방 선언은 이러한 세부 정보를 제공할 수 없으며 "오류: 필드 'b'에 불완전한 유형 'B'가 있음"과 같은 문제가 나타납니다.