【实例 1】编写一个程序,输入 N 个学生数据,包括学号、姓名、成绩,要求输出这些 学生数据并计算平均分。
分析:设计一个学生类 CStudent,除了包括 ID(学号)、name(姓名)和 score(成绩)
数据成员外,有三个静态变量 number、sum 和 average,分别存放学生人数、学生的总成绩和 学生的平均成绩,普通成员函数 print()输出姓名、编号和成绩等信息,静态成员函数 Aver()用 于计算平均分,友元函数 show()输出学生的总人数和全部成绩,在 main()函数中定义了一个对 象数组用于存储输入的学生数据。
#include <iostream>
using namespace std;
class CStudent{
private:
char* name; //学生姓名 char* ID; //学号
float score; //学生成绩 static int number;//学生人数 static float sum;//学生的总成绩
static float average; //学生的平均成绩 public:
CStudent(char* s,char * n,float a);
static void Aver();//求平均成绩
void print(); //输出姓名、编号和成绩等信息
friend void show(CStudent &);//友元函数输出学生的数量和成绩
~CStudent() {
delete [] name;
delete [] ID;
number--;
sum-=score;
} };
CStudent::CStudent(char* s,char * n,float a) {
name=new char[strlen(s)+1];
strcpy(name,s);
ID=new char[strlen(n)+1];
strcpy(ID,n);
score=a;
number++; //学生人数增加 sum+=score; //累加总成绩
129 }
void CStudent::print() {
cout<<"学生姓名:"<<name<<endl;
cout<<"学生编号:"<<ID<<endl;
cout<<"学生成绩:"<<score<<endl;
}
void show(CStudent &student) {
cout<<"学生的总人数:"<<CStudent::number<<endl;//非静态成员函数访问静态成员 cout<<"学生的总成绩"<<CStudent::sum<<endl;
}
void CStudent::Aver() {
average=sum/number;
cout<<"学生的平均成绩:"<<average<<endl;
}
//静态数据成员初始化 int CStudent::number=0;
float CStudent::sum=0;
float CStudent::average=0;
void main() {
CStudent student[4]={CStudent("张三","0809001",80),CStudent("李四", "0809002",90),CStudent("王五","0809003",90),CStudent("马六","0809004",80)};
for (int i=0;i<4;i++) {
student[i].print();
}
show(student[4]);
student[4].Aver();
}
程序的运行结果:
学生姓名:张三 学生编号:0809001 学生成绩:80 学生姓名:李四 学生编号:0809002 学生成绩:90 学生姓名:王五 学生编号:0809003 学生成绩:90 学生姓名:马六 学生编号:0809004 学生成绩:80 学生的总人数:4
130
学生的总成绩 340 学生的平均成绩:85
【实例 2】参考本书第 1 章 1.4 中的实例 1,利用本章讲到的友元类和友元函数,写一个 能输出一年 12 个月的年历程序。
分析:在第 1 章 1.4 节的实例 1 中,日期使用结构类型,在此可以修改为包含一个友元类 的类类型:
class Date {
public:
int month;
int day;
int year;
private:
friend TdateType; //定义 TdateType 类为 Date 类的友元类 };
对于 TdateType 类,作如下修改:
class TdateType {
public:
TdateType(); //不带参数的构造函数定义 TdateType(Date &b); //有参数的构造函数定义
void Modify(int m = 10,int d = 1,int y = 2009); //修改日期 void GetIn(int y);
int Weekday(); //判断是星期几成员函数定义 void Print(); //打印日期
friend void show(); //声明 show()函数为类的友元函数 private:
Date a; //对象成员
int IsLeapYear(); //成员函数,判断是否闰年 int MonthEnd(int m); //计算某月的天数 };
类的成员函数的定义:
TdateType::TdateType() {
a.year=1999;
a.month=1;
a.day=1;
}
TdateType::TdateType(Date &b) {
a.month = b.month;
a.day = b.day;
a.year = b.year;
}
void TdateType::Modify(int m,int d,int y)
131 {
a.month = m;
a.day = d;
a.year = y;
}
void TdateType::GetIn(int y) {
a.year=y;
}
int TdateType::IsLeapYear() {
return ( (a.year % 4==0 && a.year % 100!=0 )||(a.year % 400==0) );
}
int TdateType::MonthEnd(int m) {
switch(m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: return 31;
case 4:
case 6:
case 9:
case 11:return 30;
case 2:
if (IsLeapYear()) return 29;
else
return 28;
}
return 0;
}
int TdateType::Weekday() {
long n;
n=((a.year)-1)*365; //直至去年的天数(不考虑闰年) n+=((a.year)-1)/4; //以下 3 条语句考虑闰年数 n-= ((a.year)-1)/100;
n+=((a.year)-1)/400;
for ( int i=1;i<a.month;i++) //本年直至上月的天数 n+=MonthEnd(i);
n +=a.day; //本月的天数
132
n %=7; //折算成星期几,若 0,则为星期日 return n;
}
void TdateType::Print() {
for(int i=0;i<=6;i++)cout<<weekdays[i]<<" ";
cout<<endl; //输出星期 char arr=32;int j=0;
for(j=0;j<Weekday()*5;j++)cout<<arr; //输出每月 1 号所在行之前的空格 int array[31]; //定义一个月的日期
for(int k=1;k<=MonthEnd(a.month);k++) {
int m=k+Weekday()-1;
if(m%7==0&&m>6) cout<<endl; //日期超出周六后输出换行符 array[k-1]=k; //向数组内输入日期
cout<<array[k-1]<<" "; //输出日期之间的空格
if(k<10)cout<<" "; //输出占一个字符的日期多余的空格 }
cout<<endl;
}
友元函数 show()的定义:
void show() {
TdateType d;
for((d.a).month=1;(d.a).month<=12;(d.a).month++) {
d.Modify((d.a).month,(d.a).day,(d.a).year);
cout<<(d.a).month<<"月份:"<<endl;
d.Print();
} }
程序的主函数是:
int main() {
int year;
TdateType Getdata;
cout<<"请输入年份:"<<endl;
cin>>year;
Getdata.Modify();
Getdata.GetIn(year);
cout<<year<<"年的年历为:"<<endl;
show();
return 0;
}
注意,调试上述程序时,应该在定义类 Date 之前先声明 class TdateType 类,即增加如下 语句:
133 class TdateType;
程序的执行结果是:
请输入年份:
2010
2010 年的年历为:
1 月份:
Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
2 月份:
Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
3 月份:
Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
… …