我是C ++的新手,我在头文件中遇到了类定义问题。 头文件(Student.h)的代码是:
#include <string>
using namespace std;
class Student
{
// Data Members for a Student
string id;
string preferences[3];
int skill;
// Constructor
public:
Student(){}
public:
void SetID(string str)
{ this->id = str; }
public:
void SetSkill(int i)
{ this->skill = i; }
public:
void SetPreferences(int i, string s)
{
this->preferences[i] = s;
}
};
class StudentSchedule
{
public:
StudentSchedule(){}
};
编译错误表示第14行(学生类)是'学生'的重新定义,第15行({ - 类学生后面的开放式大括号)是先前的'学生'定义。 StudentSchedule类存在前两个连续行的相同错误。
我的编译中没有定义任何类的.c,.cpp或.h文件。我不知道为什么我会收到这个错误。
答案 0 :(得分:24)
该头文件需要header guards。它可能被包括两次。
修改标题,将这些行添加到开头和结尾。
#ifndef STUDENT_H
#define STUDENT_H
// Put the entire contents of your header here...
#endif
定义不需要是STUDENT_H
......它只需要是唯一的。
添加了这些指令后,如果头文件已被解析,编译器将忽略该文件的所有内容。
或者,而it is not standard C++,所有主要编译器都允许你放一个
#pragma once
作为标题的第一行,以防止多次解析它。
答案 1 :(得分:4)
你可能包括.h文件两次,第一次定义学生,第二次尝试重新定义它。
请参阅Wikipedia entry on include guards以获取有关问题的更详尽说明以及有关如何避免此问题的信息。
简而言之,有两种方法可以做到这一点
版本1,#define包括警卫
#ifndef STUDENT_HPP
#define STUDENT_HPP
...your code here...
#endif
通常#define被称为文件名的一些变体,因为它必须在每个包含文件中都不同。
版本2,#pragma一次
#pragma once
...your code here...
这个pragma(对于大多数编译指示)不能移植到所有编译器,但是some of the most important ones。它还具有不需要手动指定名称的优点。
您使用的由您决定,但您很可能必须选择一个:)
答案 2 :(得分:3)
我更喜欢使用
#pragma once
作为头文件的第一行,而不是定义。即使这是非标准的,它也可以避免名称冲突并减少编译时间。
答案 3 :(得分:0)
当我学习c ++时,我们的教授说,你在c ++类中编写的前两行应该总是#ifndef,然后是#define。这可以防止头文件中的多个定义
http://www.fredosaurus.com/notes-cpp/preprocessor/ifdef.html