12

我是 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 文件。我不知道为什么会收到此错误。

4

4 回答 4

32

您需要对该头文件进行标头保护。它可能被包括两次。

修改标题,将这些行添加到开头和结尾。

#ifndef STUDENT_H
#define STUDENT_H

// Put the entire contents of your header here...

#endif

定义不需要是STUDENT_H......它只需要是唯一的。

添加这些指令后,如果头文件已经被解析,编译器将忽略头文件的所有内容。

或者,虽然它不是标准的 C++,但所有主要的编译器都允许您将单个

#pragma once

作为标题的第一行,以防止它被多次解析。

于 2012-01-22T19:59:54.967 回答
4

您可能包含 .h 文件两次,第一次将定义 Student,第二次将尝试重新定义它。

有关该问题的更广泛解释以及有关如何避免该问题的信息,请参见包含警卫的 Wikipedia 条目。

简而言之,有两种方法可以做到

版本 1,#defined 包括警卫

#ifndef STUDENT_HPP
#define STUDENT_HPP

...your code here...

#endif

通常 #define 被称为文件名的某种变体,因为它在每个包含文件中都必须不同。

版本 2,#pragma once

#pragma once

...your code here...

这个 pragma (和大多数 pragma 一样)不能移植到所有编译器,而是一些最重要的编译器。它还具有不需要手动分配名称的优点。

您使用哪个取决于您,但您很可能必须选择一个:)

于 2012-01-22T20:00:41.023 回答
3

我更喜欢使用

   #pragma once

作为头文件的第一行,而不是定义。即使这是非标准的,它确实避免了名称冲突并可以减少编译时间。

于 2012-01-22T20:04:41.177 回答
0

当我学习 c++ 时,我们的教授说,你在 c++ 类中编写的前两行应该始终是#ifndef,然后是#define。这可以防止头文件中的多个定义

http://www.fredosaurus.com/notes-cpp/preprocessor/ifdef.html

于 2012-01-22T22:47:32.553 回答