循环包含在C++中

Circular includes in C++ - again

本文关键字:C++ 包含 循环      更新时间:2023-10-16

Main.cpp

#include "Test1.h"
#include "Test2.h"
int main(){  
    Test1 t1;
    Test2 t2;
    t1.process(t2);
    t2.process(t1);
} 

测试1.h

#ifndef TEST1
#define TEST1
#include "Test2.h"
class Test1 {
public:
    void process(const Test2& t) {};
};

#endif // !TEST1

测试2.h

#ifndef TEST2
#define TEST2
#include "Test1.h"
class Test2 {
public:
    void process(const Test1& t) {};
};

#endif // !TEST2

VS2012表示:

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2143: syntax error : missing ',' before '&'
error C2664: 'Test2::process' : cannot convert parameter 1 from 'Test1' to 'const int'

我很确定这是循环包含的问题(我偶尔会遇到它(,但这次我不确定为什么不编译。

注意:类只依赖于彼此的引用,这些引用的大小是已知的。是因为包含保护(#ifndef(,使得其中一个测试头将另一个作为空文件包含吗?

如果您坚持这样做,您需要在每个.h文件中转发声明您的类,以便编译器知道它是什么。

#include "Test1.h"
class Test1;
class Test2 {
public:
    void process(const Test1& t) {};
};

完全展开预处理器指令,您会看到问题:Main.cpp包含Test1.h,其中包含Test2.h,因此在定义Test1之前,将首先编译class Test2,从而导致missing type specifier错误。您可能可以通过前向声明Test1并说void process(const class Test1& t)而不仅仅是void process(const Test1& t)来解决此问题。

您需要在其中一个的头中放入另一个的前向声明。如果在Test2.h中转发声明Test1(在声明Test2之前(,则可以从Test2.h删除#include "Test1.h"

如果您在头中有一个指向类型的引用或指针,请尝试使用前向声明。

// Within stop Test2.h
class Test1;

test1.htest2.h中,可以分别使用Test2Test1的前向声明来避免包含。只需将class Test1;替换为#include "test1.h"即可。

然后仅在实现文件中包含test1.h

请参阅此问题