C++類與對象函數題——6-1 學生成績的快速錄入(構造函數) (10分)(含總結和易錯點解析)

現在需要錄入一批學生的成績(學號,成績)。其中學號是正整數,並且錄入時,後錄入學生的學號會比前面的學號大;成績分兩等,通過(Pass,錄入時用1代表),不通過(Fail,錄入時用0代表)。

由於很多學號都是相鄰的,並且學號相鄰的學生成績常常相同。所以在錄入時,適當地加了速。如果當前學生的學號比前面的學號大1,且成績與前面的成績相同,則只輸入0即可。

類定義:
完成Student類
裁判測試程序樣例:
#include
using namespace std;

/* 請在這裏填寫答案 */

int main(){
const int size=100;
int i, N, no, score;
Student *st[size];
cin>>N;
for(i=0; i<N; i++){
cin>>no;
if(no>0){
cin>>score;
st[i]=new Student(no, score);
}
else
st[i]=new Student(*st[i-1]);
}
cout<<Student::count<<" Students"<<endl;
for(i=0;i<N;i++) st[i]->display();
for(i=0;i<N;i++) delete st[i];
return 0;
}

輸入樣例:
5
3 0
0
7 1
0
12 1
輸出樣例:
5 Students
3 Fail
4 Fail
7 Pass
8 Pass
12 Pass

class Student{
    int m_no;
    int m_score;
  public:
    static int count;
    Student(){}
    Student(int no,int score):m_no(no),m_score(score){count++;}
//拷貝構造函數
    Student(const Student &s){
        m_no=s.m_no+1;
        m_score=s.m_score;
        count++;
    }
    void display(){
        cout<<m_no<<" ";
        if(m_score)cout<<"Pass\n";
        else cout<<"Fail\n";
    }
};
int Student::count=0;

函數名稱的作用域也可以是全局的,但不能是局部的。C++類引入了一種新的作用域:類作用域。
在類中定義的名稱(如類數據成員和類成員函數名)的作用域都爲整個類,作用域爲整個類的名稱只在該類中是已知的,在類外是不可知的。因此,可以在不同類中使用相同的類成員名而不會引起衝突。也就是說,要調用公有成員函數,必須通過對象:同樣,在定義成員函數時,必須使用作用域解析運算符。

static int count;

這將創建一個名爲count的變量,該變量將與其他靜態變量儲存在一起,而不是存儲在對象中。因此,只有一個count變量,被所有Student對象共享。
一定要注意該靜態變量的初始化:
c++中靜態成員變量要在類外部再定義,否則產生link2001錯誤.

爲什麼要在類的外部進行定義的原因:

  1. 在類中,只是聲明瞭靜態變量,並沒有定義。
  2. 聲明只是表明了變量的數據類型和屬性,並不分配內存;定義則是需要分配內存的。
    注意:如果在類裏面這麼寫int a; 那麼是既聲明瞭變量,也定義了變量,兩者合在一起了。
  3. 靜態成員是“類級別”的,也就是它和類的地位等同,而普通成員是“對象(實例)級別”的。
    類級別的成員,先於該類任何對象的存在而存在,它被該類所有的對象共享。
  4. 現在,咱們假定要實例化該類的一個對象,那麼會發生什麼事情呢?
    靜態成員肯定要出現在這個對象裏面的,對吧?這時候纔去定義那個靜態成員嗎?這顯然是不合適的。
    因爲,比如有另外一個線程也要創建該類的對象,那麼也要按照這個方式去定義那個靜態成員。
    這會產生兩種可能的情況:
    A. 重複定義;
    B. 就算不產生重複定義的情況,也會產生競爭,從而造成死鎖的問題,以至於對象無法創建。
    很顯然,編譯器不能這麼幹。那麼很合理的解決辦法,就是事先在類的外部把它定義好,然後再供所有的對象共享。
    當然這樣做,還是有可能產生線程安全的問題,但不管怎麼說對象是創建好了,而這種線程安全問題,可以在編程中予以解決。

對於class的static data member,其實只是聲明瞭一個scope(還記得class::static_data_member中的::麼?),
既然是聲明而已,所以還需要一個定義,
之所以需要在類的外面,因爲本質來說它和global和static變量沒什麼區別,都是在數據段的,只是scope不一樣,屬於class而已。

應該注意!!!!!!!定義前應該加上該靜態變量所屬的類作用域
在本題中屬於Student類所以它的類外定義應該這樣寫:
int Student::count=0;

By——Suki

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章