2010-12-05 17 views
0

私はPersonとStudentの2つのクラスを持っています。私は現在、PersonクラスからStudentクラスを派生しようとしています。リンクエラーC++継承

ただし、リンクエラーが発生しています。

エラー:

[Linker error] undefined reference to `Person::Person()' 

マイコード:

#include <iostream> 
#include <iomanip> 
using namespace std; 

class Person { 

    string Name ; 

public: 
    Person(void); 

    void set(){ 

     cout << "Name:" << endl ; 
     cin >> Name ; 
     } 

    string get_Name(){ 
     return Name ; 
     } 


}; 

class Student:Person { 
    int x, Lab1, Lab2, Lab3, Lab4, Lab5, Lab6, LabPoints, Midterm, Final ; 
    float LabAvg, ExamAvg, Prcnt ; 
    string StuName ; 

public: 
    Student(void); 

    void set(int i){ 
     x = i; 

     cout << "Student " << x << endl << endl ; 
     cout << "Name:" << endl ; 
     cin >> StuName ; 
     cout << "Lab 1 score (1-10): " << endl ; 
     cin >> Lab1 ; 
     cout << "Lab 2 score (1-10): " << endl ; 
     cin >> Lab2 ; 
     cout << "Lab 3 score (1-10): " << endl ; 
     cin >> Lab3 ; 
     cout << "Lab 4 score (1-10): " << endl ; 
     cin >> Lab4 ; 
     cout << "Lab 5 score (1-10): " << endl ; 
     cin >> Lab5 ; 
     cout << "Lab 6 score (1-10): " << endl ; 
     cin >> Lab6 ; 
     cout << "Midterm score (1-100): " << endl ; 
     cin >> Midterm ; 
     cout << "Final score (1-100): " << endl ; 
     cin >> Final ; 

     LabAvg = (Lab1 + Lab2)/2.0 ; 
     LabPoints = (Lab1 + Lab2) ; 
     ExamAvg = (Midterm + Final)/2.0 ; 
     Prcnt = (((LabPoints/60.0) * 0.6) + ((Midterm/100.0) * 0.2) + 
     ((Final/100.0) * 0.2)) * 100 ; 

     } 

    string get_StuName(){ 
     return StuName ; 
     } 

    int get_Lab1(){ 
     return Lab1 ; 
     } 

    int get_Lab2(){ 
     return Lab2 ; 
     } 

    int get_Lab3(){ 
     return Lab3 ; 
     } 

    int get_Lab4(){ 
     return Lab4 ; 
     } 

    int get_Lab5(){ 
     return Lab5 ; 
     } 

    int get_Lab6(){ 
     return Lab6 ; 
     } 

    float get_LabAvg(){ 
     return LabAvg ; 
     } 

    int get_LabPoints(){ 
     return LabPoints ; 
     } 

    float get_ExamAvg(){ 
     return ExamAvg ; 
     } 

    float get_Prcnt(){ 
     return Prcnt ; 
     } 
}; 

Student::Student(void){ 
    x = 0, Lab1 = 0, Lab2 = 0, Lab3 = 0, Lab4 = 0, Lab5 = 0, Lab6 = 0, 
    LabPoints = 0, Midterm = 0, Final = 0 ; 
    LabAvg = 0.0, ExamAvg = 0.0, Prcnt = 0.0 ; 
    StuName = "" ; 
} 

int main(){ 
    int MaxNumStu = 10, NumOfRep , i ; 
    float FPrcnt ; 
    string LetGrd ; 

    cout << "Number of Students:" << endl ; 
    cin >> NumOfRep ; 
    cout << endl << endl ; 

    Student obs[MaxNumStu] ; 

    NumOfRep = ++NumOfRep ; 
    for(i=1 ; i < NumOfRep ; i++) 
    obs[i].set(i) ; 

    cout << endl << "---------------------------------" << endl << endl ; 

    for(i=1; i < NumOfRep; i++){ 
    cout << obs[i].get_StuName() << endl << endl; 
    cout << "Lab 1 Score: " << obs[i].get_Lab1() << endl ; 
    cout << "Lab 2 Score: " << obs[i].get_Lab2() << endl ; 
    cout << "Lab 3 Score: " << obs[i].get_Lab3() << endl ; 
    cout << "Lab 4 Score: " << obs[i].get_Lab4() << endl ; 
    cout << "Lab 5 Score: " << obs[i].get_Lab5() << endl ; 
    cout << "Lab 6 Score: " << obs[i].get_Lab6() << endl ; 
    cout << endl << "Average Lab Score: " << setprecision(4) << 
    obs[i].get_LabAvg() << endl ; 
    cout << "Total Lab Points: " << obs[i].get_LabPoints() << endl ; 
    cout << endl << "Average Exam Score: " << setprecision(4) << 
    obs[i].get_ExamAvg() << endl ; 

    FPrcnt = obs[i].get_Prcnt() ; 

    if (FPrcnt >= 90) 
     LetGrd = "% A" ; 
    if (FPrcnt >= 80) 
     if (FPrcnt < 90) 
      LetGrd = "% B" ; 
    if (FPrcnt >= 70) 
     if (FPrcnt < 80) 
      LetGrd = "% C" ; 
    if (FPrcnt >= 60) 
     if (FPrcnt < 70) 
      LetGrd = "% D" ; 
    if (FPrcnt < 60) 
     LetGrd = "% F"; 

    cout << endl << endl << "Overall Grade: " << setprecision(3) << FPrcnt 
    << LetGrd << endl; 
    cout << endl << endl ; 
    } 
    system("pause") ; 
} 

答えて

4

あなたはPersonのデフォルトコンストラクタを宣言しました。

この場合、独自のデフォルトコンストラクタを用意する必要はありません。宣言を削除し、コンパイラでデフォルトを生成させます。

Person::Person() 
{ 
} 
1

あなたは人::人()ライン10上を宣言していますが、それを定義することはありません。

public: 
    Person(void); 

をしかし、それを定義したことはありません:

3

あなたはそれを定義せずPerson::Person(void);を宣言している: また、あなたがdo-nothingを定義することはできません。

この行を削除しても問題ありません。派生クラスのコンストラクタ、コンパイラが生成メンバ関数

1

この質問はC++の2の基本的な概念に関連しています。

派生クラスのコンストラクタの場合、最初に基本クラスのコンストラクタを呼び出す必要があります。この場合、

Student::Student(void){ 
    x = 0, Lab1 = 0, Lab2 = 0, Lab3 = 0, Lab4 = 0, Lab5 = 0, Lab6 = 0, 
    LabPoints = 0, Midterm = 0, Final = 0 ; 
    LabAvg = 0.0, ExamAvg = 0.0, Prcnt = 0.0 ; 
    StuName = "" ; 
} 

使用するクラスPersonのコンストラクタは指定しません。したがって、コンパイラはPersonクラスのデフォルトコンストラクタであるPerson:Person()の呼び出しを自動的に挿入します。彼らは宣言されていないをしている場合

は、コンパイラが生成機能では、コンパイラは、各クラスのものを、次のメンバ関数を生成します

  • デフォルトのコンストラクタ
  • コピーコンストラクタ
  • 代入演算子
  • デストラクタ

デフォルトコンストラクタは、コンパイラによって生成されないように、しかし、クラスPersonは、コンストラクタPerson:Person(void)を宣言しました。 StudentクラスのPerson:Person()をリンクすると、リンクエラーがコンパイラによってスローされます。

リンクエラーには2つの解決策があります。

  1. Person::Person(void);の減速を消去するので、デフォルトのコンストラクタが生成されます。
  2. Person::Person(void);の定義を追加します。リンカは独自のデフォルトコンストラクタを使用します。

拡張するには、クラスpersonで定義されたコンストラクタがPerson:Person(string name)であると仮定します。 解決策2はまた、クラスStudentのコンストラクタを変更する必要があります。

Student::Student(void):Person("any string"){ 
    x = 0, Lab1 = 0, Lab2 = 0, Lab3 = 0, Lab4 = 0, Lab5 = 0, Lab6 = 0, 
    LabPoints = 0, Midterm = 0, Final = 0 ; 
    LabAvg = 0.0, ExamAvg = 0.0, Prcnt = 0.0 ; 
    StuName = "" ; 
}