第3 章 怎样使用类和对象 1.构造函数和析构函数的作用是什么?什么时候需要自己定义构造函数和析构 函数? 【解】略。 2.分析下面的程序,写出其运行时的输出结果。 #include using namespace std; class Date {public: Date(int,int,int) ; Date(int,int) ; Date(int) ; Date() ; void display() ; private: int month; int day; int year; }; Date::Date(int m,int d,int y): month(m),day(d),year(y) { } Date::Date(int m,int d): month(m),day(d) {year=2005; } Date::Date(int m):month(m) {day=1; year=2005; } Date::Date() 28 C++面向对象程序设计(第3 版)学习辅导 {month=1; day=1; year=2005; } void Date::display( ) {cout< using namespace stdd; class Date {publicc: Date((int=1,int=1,int=2005) ; void display() ; privatte: int mmonth; int dday; int yyear; }; Date::Date(int m,innt d,int y):month(m),dayy(d),year(y) ) { } void Date::display(( ) {cout<< using namespace stdd; class Student {publicc: Studeent(int n,float s):num(nn),score(s){ } void display() ; privatte: 30 C++面向对象程序设计(第3 版)学习辅导 int num; float score; } ; void Student::display( ) {cout<display(); return 0; } 运行时的输出如下: 101 78.5 103 98,5 105 95.5 5.建立一个对象数组,内放5 个学生的数据(学号、成绩),设立一个函数max, 用指向对象的指针作函数参数,在max 函数中找出5 个学生中成绩最高者,并输出其 学号。 【解】程序如下: #include using namespace std; class Student {public: Student(int n,float s):num(n),score(s){ } int num; float score; }; int main() {Student stud[5]={ Student(101,78.5),Student(102,85.5),Student(103,98.5), Student(104,100.0),Student(105,95.5)} ; void max(Student. ) ; Student .p=&stud[0] ; max(p) ; return 0; } 第3 章怎样使用类和和对象 31 void max(Student .aarr) {floatt max_score=aarr[0].scoree; int kk=0; for(int i=1;i<5;ii++ ) if(aarr[i].scoree>max_score) {max_score==arr[i].scorre;k=i; } cout< using namespace stdd; class Student {publicc: Studeent(int n,float s):num(nn),score(s){ } void change(int n,float s) {{num=n;scoree=s; } void display() {cout<display() ; p–>change(101,80.5) ; p–>display() ; return 0; } 其他部分仍同第6 题的程序。 (4)在(3)的基础上将main 函数第3 行改为 const Student .p=&stud; (5)再把main 函数第3 行改为 Student .const p=&stud; 【解】 (1)有两个错误: ① stud 被声明为常对象后,不能调用对象中的一般成员函数(除非把该成员函数也 声明为const 型),因此在main 函数中调用stud.display( ) 和stud.change( ) 是非法的。 ② 若将对象stud 声明为常对象,其值是不可改变的,而在主程序中,企图用 stud.change 函数去改变stud 中数据成员的值,是非法的 。 因此程序在编译时出错。如果将程序第7 行改 为 void display() const {cout< using namespace std; class Student {public: Student(int n,float s):num(n),score(s){} void change(int n,float s) const {num=n;score=s;} //常成员函数 void display()const {cout< using namespace stdd; class Student {publicc: Studeent(int n,float s):num(nn),score(s){ } void change(int n,float s) {{num=n;scoree=s; } void display() {cout<display() ; p–>chhange(101,80..5) ; p–>display() ; returrn 0; } 在主函数数中定义了指针针对象p,它指向stud,函数pp–>display() 相相当于stud.dispplay() 。 程序合法,运运行结果与第66 题程序的运行行结果相同。 (4)在((3)的基础上将main 函数第第3 行改为 const SStudent .p=&stud; 34 C++面向对象程序设计(第3 版)学习辅导 程序如下: #include using namespace std; class Student {public: Student(int n,float s):num(n),score(s){ } void change(int n,float s) {num=n;score=s; } void display() {cout<display() ; p–>change(101,80.5) ; p–>display() ; return 0; } 在主函数中定义了指向const 对象的指针变量p,则其指向的对象的值是不能通过指 针变量p 改变的。为了安全,C++ 也不允许通过指针变量p 调用对象stud 中的非const 成员函数,在main 函数中调用p–>display( ) 和p–>change( ) 是非法的。为了能正确调用 stud 中的display 函数,应将程序第7 行改为 void display() const {cout<change( ) 企图通过指针变量p 修改类中的数据成员的值,这也是和指向 const 对象的指针变量的性质不相容的,编译时出错。 在上面的基础上,将程序改为 #include using namespace std; class Student {public: Student(int n,float s):num(n),score(s){} void change(int n,float s) {num=n;score=s;} void display() const{cout<dissplay() ; stud.cchange(101,880.5); // 注意此行行修改 了 p–>dissplay() ; returnn 0; } 在main 函数中,不是是通过指针变量量p 修改数据成成员,而直接通通过对象名stuud 调用 change 函数,则是允许的,编译能通过。因为并未定义义stud 为常对象象,只是定义了p 是 指向const 对对象的指针变量量,不能通过指指针变量p 修改改类中的数据成成员的值,而不不通过 指针变量p 修修改类中的数据据成员的值是可可以的。 同样,如如果不是通过指指针变量p 调用用display 函数(即p->displaay( );),而是通通过对 象名stud 调用用display 函数,则不必将diisplay 函数声明明为const 型。 (5)再把把main 函数第3 行改为 Student .const p=&sstud; 定义了一个指指向对象的常指指针,要求指针针变量p 的指向向不能改变,只能能始终指向对象stud。 今在程序中未未改变p 的指向向,因此程序合合法,而且不需需要在定义display 和changge 函数 时将它们声明明为const 型。程序能通过编编译,并正常运运行。运行的结结果与第6 题的程序 的运行结果相相同。 8.修改第第6 题的程序,,增加一个funn 函数,改写mmain 函数。在m 调用fun main 函数中调 函数,在fun 函数中调用chhange 和displaay 函数。在fuun 函数中使用对对象的引用(SStudent &)作为形参参。 【解】可可以编写以下程程序: #include using namespace stdd; class Student {publicc: Studeent(int n,float s):num(nn),score(s){ } void change(int n,float s) {{num=n;scoree=s; } void display() {cout< using namespace std; class Product {public: Product(int m,int q,float p):num(m),quantity(q),price(p){}; void total(); static float average(); static void display(); private: int num; int quantity; float price; static float discount; //销货员号 //销货件数 //销货单价 //商店统一折扣 第3 章怎样使用类和和对象 37 statiic float summ; //总销售 款 statiic int n; //商品销售总总件 数 } ; void Product::totall() //求销售款和和销售件数 {float rate=1.0; if(quaantity>10) rrate=0.98.ratte; sum=suum+quantity.price.rate.((1–discount); //累计销售款 款 n=n+quuantity; //累计销售件件 数 } void Product::displlay() //输出销售总总件数和平均 价 {cout<< using namespace std; class Date; //对Date的声明,它是对Date的预引 用 class Time {public: Time(int,int,int); friend void display(const Date &,const Time &); // 将普通函数display声明为朋友 private: int hour; int minute; int sec; }; Time::Time(int h,int m,int s) {hour=h; minute=m; sec=s; } class Date {public: Date(int,int,int); friend void display(const Date &,const Time &); // 将普通函数display声明为朋友 private: int month; int day; int year; }; Date::Date(int m,int d,int y) {month=m; day=d; year=y; } void display(const Date &d,const Time &t) //是Time和Date两个类的朋友 { cout< using namespace stdd; class Time; class Date {publicc: Date((int,int,intt); friennd Time; privatte: int month; int day; int year; }; ///将Time类声明明为朋友类 Date::Date(int m,innt d,int y):month(m),dayy(d),year(y)){} class Time {publicc: Time((int,int,intt) ; void display(connst Date &) ; privatte: int hour; int minute; int sec; }; Time::Time(int h,innt m,int s):hour(h),minuute(m),sec(ss){} 40 C++面向对象程序设计(第3 版)学习辅导 void Time::display(const Date &d) { cout< using namespace std; template class Compare {public: Compare(numtype a,numtype b) ; numtype max() ; numtype min() ; private: numtype x,y; } ; //在类模板外定义各成员函 数 template Compare::Compare(numtype a,numtype b) {x=a;y=b;} 第3 章怎样使用类和和对象 41 template numtype Compare::max(( ) {returnn (x>y)?x:y;; } template numtype Compare::min(( ) {returrn (x cmp11(3,7); cout< cmmp2(45.78,933.6); cout< cmpp3('a','A' ); cout<