2012-01-22 15 views
7

私は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({であることを言いますclass Studentに続くブレース)は、以前の「Student」の定義です。 StudentScheduleクラスの最初の2つの連続した行に同じエラーが存在します。

いずれのクラスも定義しているコンパイルのどこにも、.c、.cpp、または.hファイルがありません。なぜこのエラーが出るのか分かりません。

答えて

18

このヘッダファイルにはheader guardsが必要です。おそらく2回含まれています。

ヘッダーを変更し、これらの行を先頭と末尾に追加します。

#ifndef STUDENT_H 
#define STUDENT_H 

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

#endif 

ザ・定義は、それだけでユニークである必要があります... STUDENT_Hである必要はありません。

これらのディレクティブを追加すると、ヘッダーファイルがすでに解析されている場合、コンパイラはヘッダーファイルのすべての内容を無視します。また

it is not standard C++ながら、すべての主要なコンパイラを使用すると、複数回解析されてからそれを防ぐために、ヘッダーの最初の行として単一

#pragma once 

を置くことができます。

3

おそらく.hファイルを2回追加します。最初はStudentを定義し、2回目はそれを再定義しようとします。

問題の詳細な説明と回避方法については、Wikipedia entry on include guardsを参照してください。要するに

、#defineで定義それに

バージョン1を行うには、2つの方法があるが、それは違うしなければならないため警備員が

#ifndef STUDENT_HPP 
#define STUDENT_HPP 

...your code here... 

#endif 

通常の#defineは、ファイル名の一部のバリエーションと呼ばれるが含ますべてのインクルードファイルで

バージョン2は、#pragmaは一度

#pragma once 

...your code here... 

このプラグマは、(ほとんどのプラグマなど)すべてのコンパイラへの移植ではなく、some of the most important ones。また、手動で割り当てられた名前を必要としないという利点もあります。あなたが使用

はあなた次第ですが、最も可能性の高いものを選択する必要が:)

2

私が代わりに定義の、ヘッダファイルの最初の行として

#pragma once 

を使用して好みます。これが非標準であっても、名前の衝突を避けてコンパイル時間を短縮することができます。

+1

を防ぐには(確かにシンプルな)うれしいですが、それはそう、それが唯一の欠点である、標準C++ –

+0

ではありません。私にとって、利点はこれを上回っています。 –

関連する問題