我在2个不同的文件中有2个类:
RegMatrix.h:
#ifndef _RM_H
#define _RM_H
#include "SparseMatrix.h"
...
class RegMatrix{
...
RegMatrix(const SparseMatrix &s){...} //ctor
...
};
#endif
SparseMatrix.h:
#ifndef _SM_H
#define _SM_H
#include "RegMatrix.h"
...
class SparseMatrix{
...
SparseMatrix(const RegMatrix &r){...} //ctor
...
};
#endif
在构造函数行上我得到错误:
错误C4430:缺少类型说明符 - 假设为int。
错误C2143:语法错误:在'&'
之前缺少','但是当我添加类声明
时class SparseMatrix;
RegMatrix.h文件中的和
class RegMatrix;
在SparseMatrix.h文件中它工作正常。 我的问题是,如果我有包含,为什么需要它? 10倍。
答案 0 :(得分:10)
你不能有循环#includes(一个文件#includes另一个#includes第一个文件)。前面声明其中一个类而不是#include会打破链并允许它工作。声明类名允许您使用该名称,而无需了解该类的内部位。
顺便说一下,对圆形#includes的渴望是一种设计气味。也许你可以创建一个两个类可以依赖的接口?然后他们就不必相互依赖。答案 1 :(得分:5)
你的标题包含不起作用,看看如果我在解析包括后包含SparseMatrix.h会发生什么:
#ifndef _SM_H
#define _SM_H
/// start of #include "RegMatrix.h"
#ifndef _RM_H
#define _RM_H
/// start of #include "SparseMatrix.h" inside "RegMatrix.h"
#ifndef _SM_H
// skipping, because _SM_H is defined and the condition is false
#endif
/// end of #include "SparseMatrix.h" inside "RegMatrix.h"
class RegMatrix{
...
RegMatrix(const SparseMatrix &s){...} //ctor
...
};
#endif
/// end of #include "RegMatrix.h"
...
class SparseMatrix{
...
SparseMatrix(const RegMatrix &r){...} //ctor
...
};
#endif
基本上,SparseMatrix未定义。你无能为力。只需申报你的班级前瞻声明。
答案 2 :(得分:3)
如果您先包含RegMatrix.h
,则会包含SparseMatrix.h
。然后,这将返回到包括RegMatrix.h
,并跳过,因为已定义标题保护。然后继续定义SparseMatrix
,除了RegMatrix
从未声明过。然后你得到一个错误。
您不能拥有循环包含。你必须转发声明其中一个或两个,就像你一样。
答案 3 :(得分:3)
之类的陈述
class SparseMatrix;
被称为前向声明。它告诉编译器“某处”有一个该名称的类。只要前向声明文件使用指针或对前向引用类的引用,它就会使编译器满意并且工作正常。那是因为从编译器的角度来看,无论类内容如何,指针或引用都只有4个字节。
在OP的代码中,SparseMatrix
和RegMatrix
都只用作(const)引用,因此前向声明足以使其工作。
但是,如果前向声明文件执行某些操作,需要编译器知道其大小,例如
void foo( SparseMatrix ); // note pass by value
然后编译器会抱怨: - )
在OP提出的特殊情况下,我倾向于完全放弃共同#include
,并根据前向声明设计界面。实现(即.cpp文件)可能必须包含两个头文件,但这不是问题。