错误:类名没有在C++中命名类型

Error: class name does not name a type in C++

本文关键字:C++ 类型 错误      更新时间:2024-05-09

我知道这个问题已经被问了很多次了,但我尝试了一些建议,比如检查拼写,确保我包含了头文件、大写字母等,但我仍然会遇到同样的错误,不知道是什么触发了它。

当我尝试使用g++-c Customer.h编译Student.h时,我得到错误"Student"没有在"Student Student;"行上命名类型我不知道为什么。有人能找出原因吗?该变量应该表示该登录id/帐户的学生,该id/帐户应该是指向student对象的指针。

同样,当我尝试编译Login.h时,我得到错误"Login"没有在Customer.h中为bool addAcct(Login*(声明,以及错误"Login'没有Login*logins[MAX_logins]的类型。

任何帮助都将不胜感激!

学生:

#ifndef STUDENT_H
#define STUDENT_H
#define MAX_LOGINS 4
#include <string>
#include "Login.h" 
using namespace std;
class Student{
public:
Student(int = 0, string = ""); 
int getId();
bool addAcct(Login*);
void print();
private:
int id;
string name;
Login* logins[MAX_LOGINS];
int numberOfLogins;
};
#endif

登录.h

#ifndef LOGIN_H
#define LOGIN_H
#include <string>
#include "Student.h"
using namespace std;
class Login{
public:
Login(int = 0, float = 0); 
int getNumber();
void setStudent();
void print();
private:
int number;
Student student;
};
#endif

这里的问题是循环依赖关系(如注释中所指出的(,而问题是处理器本质上将#include语句作为顺序文本插入来处理。

例如,当预处理器遇到#include "student.h"时,它会像一样一步一步地进行

#ifndef STUDENT_H  // <--- header guard not defined at this point, ok to proceed
#define STUDENT_H  // <--- define header guard first thing in order to prevent recursive includes
#define MAX_LOGINS 4
#include <string>
#include "Login.h"  --->  #ifndef LOGIN_H
#define LOGIN_H
#include <string>
#include "Student.h"  --->  #ifndef STUDENT_H
// entire body of student.h is skipped over
// because STUDENT_H header guard is defined
using namespace std;  <---  // so processing continues here
class Login{
// ...
Student student;   // <--- error because class Student is not defined
};

解决方案是转发声明不需要完整定义的类型,而不需要#include'相应的标头。

在这种情况下,class Login有一个成员Student student;,它需要完全定义class Student,所以login.h实际上必须是#include "student.h"

然而,class Student只携带指向Login的指针的Login* logins[MAX_LOGINS];数组,并且指针不需要类的完整定义,而只需要类型的前向声明。因此,可以将Student.h修改为前向声明class Login,这消除了循环头依赖关系,并允许代码进行编译。

// #include "Login.h"  // <--- full header not required
class Login;           // <--- forward declaration is sufficient