我上课了:
class SOMECLASS
{
public:
(...)
static SOMESTRUCT GetInfo();
};
结构:
struct SOMESTRUCT
{
(...)
SOMECLASS Instance;
};
它们在SOMESTRUCT.h和SOMECLASS.h中声明
即使使用前向声明,我也无法编译它。 我还在:
error: field ‘Instance’ has incomplete type
我该如何解决?
答案 0 :(得分:0)
尝试以下
SOMECLASS.h
#ifndef SOMECLASS_H
#DEFINE SOMECLASS_H
class SOMECLASS
{
public:
(...)
static struct SOMESTRUCT GetInfo();
};
#endif // SOMECLASS_H
SOMESTRUCT,H
#ifndef SOMESTRUCT_H
#DEFINE SOMESTRUCT_H
#include "SOMECLASS.h"
struct SOMESTRUCT
{
(...)
SOMECLASS Instance;
};
#endif // SOMESTRUCT_H
答案 1 :(得分:0)
如果用户包含SOMESTRUCT.h,上面给出的答案就是正确的。 如果用户这样做
#include "SOMECLASS.h"
int main()
{
SOMECLASS::GetInfo();
}
会发生同样的错误。
原因是编译器必须知道返回变量的完整定义;否则它在函数返回时无法知道如何构造它。
当包含SOMECLASS.h时,编译器只知道标识符SOMESTRUCT是一个sturct。如果用户调用SOMECLASS :: GetInfo,则该函数必须构造一个SOMESTRUCT,因此必须在同一文件中的该行之前给出结构的完整定义。
要解决这个问题,在SOMECLASS.h中包含SOMESTRUCT.h更合理,因此用户可以确保调用类中的任何函数都不会导致编译错误,只要它们包含标题即可。 还应该在SOMESTRUCT.h中转发声明类SOMECLASS。
如果存在仅使用SOMESTRUCT.h的情况,则SOMECLASS.h也应包含在SOMESTRUCT.h中,因为构造SOMESTRUCT需要SOMECLASS.h的定义。 您可以通过将实例变量声明为SOMECLASS&或SOMECLASS *而非SOMECLASS。
如果您真的不想公开SOMESTRUCT的详细定义,可以试试这些
使用虚拟访问器定义一个IInfo接口类,以从SOMESTRUCT获取信息
使用pimpl成语
通过这些方式,您不必在SOMECLASS.h中包含SOMESTRUCT.h。