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

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