构造函数声明中的“缺少类型说明符”错误

时间:2010-09-27 18:04:26

标签: c++ visual-studio-2008

我在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倍。

4 个答案:

答案 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的代码中,SparseMatrixRegMatrix都只用作(const)引用,因此前向声明足以使其工作。

但是,如果前向声明文件执行某些操作,需要编译器知道其大小,例如

void foo( SparseMatrix );  // note pass by value

然后编译器会抱怨: - )

在OP提出的特殊情况下,我倾向于完全放弃共同#include ,并根据前向声明设计界面。实现(即.cpp文件)可能必须包含两个头文件,但这不是问题。