面向对象程序设计实验报告
学生所在学院:信息科学与工程学院
学生所在班级:
学生姓名:
指导教师:
实验一C++基础
1.1实验目的
1.了解并熟悉开发环境,学会调试程序;
2.熟悉C++中简单的标准输入输出函数的使用方法;
3.理解const修饰符的作用并学会应用;
4.理解内联函数的优缺点并学会其使用场合;
5.理解并学会函数重载;
6.理解并熟练掌握使用new和delete来分配内存;
7.理解并熟练掌握引用的使用方法。
1.2实验内容
1.2.1程序阅读
1.理解下面的程序并运行,然后回答问题。
#include
int max_def(int x,int y)
{
return(x>y?x:y);
}
int max_def(int x,int y,int z)
{
int temp=0;
return(temp=(x>y?x:y))>z?temp:z;
}
double max_def(double x,double y)
{
return(x>y?x:y);
}
int main()
{
int x1=0;
int x2=0;
double d1=0.0;
double d2=0.0;
x1=max_def(5,6);
x2=max_def(2,3,4);
d1=max_def(2.1,5.6);
d2=max_def(12.3,3.4,7.8);-------------------------------------------------------①cout<<"x1="< cout<<"x2="< cout<<"d1="< cout<<"d2="< return 1; } 问题一:上述程序的输出结果是什么? 答:输出结果为 问题二:①处调用的是哪个函数? 答:①处调用的是double max_def(double x,double y)函数 问题三:②处的输出结果为什么是d2=12,而不是d2=12.3? 答:因为调用的int max_def(int x,int y,int z)函数返回值为整型。 2.理解下面的程序并运行,然后回答问题。 #include int main() { int*p1=new int;------------------------------------------------------① int*p2=new int(0);-------------------------------------------------------② char*p3=new char[10];----------------------------------------------------③ return 1; } 问题一:①、②、③处动态申请内存分别代表什么意思? 答:①处:定义一个整型指针动态分配一个整型空间将首地址赋给p1; ②处:定义一个整型指针动态分配一个整型空间,并赋值为0; ③处:定义一个字符型指针动态分配具有10个数组元素的字符数组空间,将 首地址赋给p3。 问题二:该程序存在什么不合理的地方? 答:程序结束时没有释放分配的存储空间。 3. 理解下面的程序并运行,然后回答问题。 #include void s a,int b) { int temp=a; a=b; b=temp; } void s*a,int*b) { int temp=*a; *a=*b; *b=temp; } int main() { int i=5; int j=10; cout<<"Before s"< s); cout<<"After the first s"< s); cout<<"After the second s"< return 1; } 问题一:输出结果是什么? 答: 问题二:①处函数调用不能实现两个数的交换,而②可以,原因是什么? 答:①处调用的函数形参为整型变量,是值传递,形参的改变不影响实参; ②处调用的函数形参为指针,是址传递,形参的改变会导致实参的改变。 问题三:②处调用的是哪个函数? 答:调用的函数是void s*a,int*b)。 实验二类和对象——类的构建 2.1 实验目的 1.类的定义; 2.类对象的使用; 3.类成员变量的定义和使用; 4.类成员函数的定义和使用; 5.理解类的作用域; 6.理解类的声明; 7.理解类中成员的访问属性; 2.2 实验内容 2.2.1程序阅读 1. 理解下面的程序并运行,然后回答后面的问题。 #include class CDate { public: void Set(int m,int d,int y) { month=m; day=d; year=y; } int IsLeapYear() { return (year%4==0 && year%100!=0)||(year%400==0); } void Print() { cout< } private: int month; int day; int year; }; void main() { CDate a; a.Set(10,15,2007); a.Print(); } 问题一:以上程序为什么不能通过编译?如何改正? 答:因为Set函数被设为私有main函数中无法调用,应在set函数前加public。问题二:类中的成员函数和成员变量分别属于哪种访问权限? 答:数据成员为私有,Print为公有;set原为私有,改正后为公有。 问题三:①处语句的意思是什么? 答:将类定义一个对象a。 2.理解下面的程序并运行,然后回答问题。 . #include int month;//全局变量 int day; int year; void Set(int m,int d,int y) { ::month=m; ::day=d; ::year=y; } class CDate { public: void Set(int m,int d,int y) { ::Set(m,d,y); } void Print() { cout< } private: int month; int day; int year; }; void main() { CDate a; a.Set(10,15,2007); a.Print(); } 问题一:①处是在给成员变量赋值还是全局变量赋值,如果去掉域作用符::,程序是否还能正确运行? 答:全局变量,不能。 问题二:②处调用的哪个函数,如果去掉域作用符::,程序是否还能正确运行?答:调用全局set函数;不能。 问题三:程序的输出结果是? 答: 实验三类和对象——构造函数与析构函数 3.1实验目的 1.理解this指针的作用和用法; 2.掌握构造函数的定义和作用; 3.掌握构造函数的使用; 4.掌握拷贝构造函数的定义和使用; 5.掌握构造函数的重载; 6.掌握析构函数的定义和使用。 3.2实验内容 3.2.1程序阅读 1.理解下面的程序并运行,然后回答问题。 #include class CPoint { public: void Set(int x,int y); void Print(); private: int x; int y; }; void CPoint::Set(int x,int y) { x=x; y=y; } void CPoint::Print() { cout<<"x="< } void main() { CPoint pt; pt.Set(10,20); pt.Print(); } 问题一:以上程序编译能通过吗?如果不能,原因是什么? 答:能通过编译。 问题二:以上程序的运行结构是否正确,如果不正确,分析为什么,如何改正?答:运行结构不正确,因为Set函数中,x=x,参数x覆盖数据成员,使得数据成员并没有被赋值。 2.理解下面的程序并运行,然后回答后面的问题。 include class CPerson { public: void Print(); private: CPerson(); private: int age; char*name; }; CPerson::CPerson() { } void CPerson::Print() { cout<<"name="< } void main() { CPerson ps(23,"张三"); ps.Print(); } 问题一:以上程序存在三个错误,在不改变主函数内容的前提下,试改正该程序。答:第一处错误是:在程序头应添加#include #include #include class CPerson { public: void Print(); CPerson(int i ,char *j); public: int age; char *name; }; CPerson::CPerson(int i,char *j) { age=i; name=j; } void CPerson::Print() { cout<<"name="< } void main() { CPerson ps(23,"张三"); ps.Print(); } 实验四类和对象—对象传递与静态成员 4.1 实验目的 1. 静态成员(静态数据成员、静态成员函数)的作用与使用时的注意事项 2.掌友元(友元函数、友元类)的作用和使用; 3. 理解常类型。 4.2 实验内容 4.2.1 程序阅读 1. 理解下面的程序并运行,然后回答后面的问题。 #include #include class CStudent { public: CStudent(char*n,int a); ~CStudent(); static void SetAge(int age); private: char*name; int age; static int nTotalObj; }; int CStudent::nTotalObj=0; CStudent::CStudent(char*n,int a) :age(a) { int nLcn=strlen(n); name=new char[nLen+1]; strcpy(name,n); name[nLen]='\0'; nTotalObj++; } CStudent::~CStudent() { delete[]name; nTotalObj--; } void CStudent::SetAge(int age) { this->age=age; } void main() { CStudent stu1("张三",25); CStudent str2("李四",26); cout<<"CStudent::nTotalObj="< } 问题一:以上程序编译能通过吗,为什么? 答:不能,CStudent::nTotalObj为私有变量,类引不能访问。 问题二:成员变量nTotalObj起什么作用,它是如何实现的? 答:统计该类所创建对象的个数,通过声明为静态。 问题三:如果不改编主函数和类Cstudent中的成员变量的属性,应该如何改正该程序? 答:可以将static int nTotalObj声明为公有。 2. 理解下面的程序并运行,然后回答后面的问题。 #include #include class CStudent { public: CStudent(char*n,int a); ~CStudent(); private: char*name; int age; }; CStudent::CStudent(char*n,int a) :age(a) { int nLen=strlen(n); name=new char[nLen+1]; strcpy(name,n); name[nLen]='\0'; } CStudent::~CStudent() { delete[]name; } class CTeacher { public: CTeacher(char*tn,int ta); ~CTeacher(); void SetStuAge(int a); private: char*name; int age; CStudent stu; }; CTeacher::CTeacher(char*tn,int ta) :age(ta) { int nLen=strlen(tn); name=new char[nLen+1]; strcpy(name,tn); name[nLen]='\0'; } CTeacher::~CTeacher() { delete[]name; } void CTeacher::SetStuAge(int a) { stu.age=a; } void main() { CStudent stu1("张三",25); CStudent str2("李四",26); } 问题一:以上程序有两个错误,指出并改正。 答:第一处错误是Cstudent age为私有,Cteacher无法访问。 第二处错误是Cteacher中Cstudent未初始化。 改正:①public:int age②Cteacher::Cteacher(char*tn,int ta)::age(ta),stu(tn,ta) 3. 理解下面的程序并运行,然后回答后面的问题。 #include class Date { private: const int year; const int month; const int day; public: Date(int y,int m,int d); void showdate(); }; Date::Date(int y,int m,int d) { year=y; month=m; day=d; } void Date::showdate() { cout< } void main() { const Date obj(2007,10,30); obj.showdate(); } 问题一:以上程序有两个错误,试指出来,并改正之? 答:第一处错误是:构造函数应该用成员初始化列表对常数据成员初始化;第二处错误是:没有用常成员函数访问常对象数据成员。改正后的程序为: #include using namespace std; class Date { private: const int year; const int month; const int day; public: Date(int y,int m,int d); void showdate()const ; }; Date::Date(int y,int m,int d):year(y),month(m),day(d) { } void Date::showdate()const { cout< } void main() { Date obj(2007,10,30); obj.showdate(); } 实验五派生与继承—单基派生 5.1 实验目的 1. 理解继承的概念; 2.理解共有派生、私有派生和保护派生; 3. 理解单基派生类中构造函数和析构函数的执行顺序。 5.2 实验内容 5.2.1 程序阅读 1. 理解下面的程序并运行,然后回答后面的问题。 #include class CBase { public: CBase(int a) :a(a) { } protected: void print() { cout<<"a="< } private: int a; }; class CDerive:public CBase { public: void print() { CBase::print(); cout<<"b="< } private: int b; } void main() { CDerive d; d.print(); CBase b; b.print(); } 问题一:以上程序有两个错误,试指出来,并改正之。 答:类CBase中的成员数据应该为公有访问属性,第二个错误是构造函数有问题。改正后的程序有两种: ① #include using namespace std; class CBase { public: CBase(int a):a(a) { } Void print() { cout<<"a="< } public: int a; }; class CDerive:public CBase { public: CDerive(int a,int b):CBase(a),b(b) { } void print() { CBase::print(); cout<<"b="< } private: int b; }; void main() { CDerive d(6,4); d.print(); CBase b(5); b.print(); } ② #include using namespace std; class CBase { public: void print() { cout<<"a="< } public: int a; }; class CDerive:public CBase { public: void print() { CBase::print(); cout<<"b="< } private: int b; }; void main() { CDerive d; d.print(); CBase b; b.print(); } 2. 理解下面的程序并运行,然后回答后面的问题。#include"iostream.h" class CBase { public: CBase(int a) :a(a) { cout<<"base structure"< } ~CBase() { cout<<"base destructure"< } void print() { cout<<"a="< } protected: int a; }; class CDerive:public CBase { public: CDerive(int a,int b,int c) :CBase(a),b(b),c(c) { cout<<"dervice structure"< } ~CDerive() { cout<<"derive destructure"< } void print() { CBase::print(); cout<<"b.a="<