资源描述
面向对象程序设计复习课(2008_秋)
一、对照书本(或上课课件),搞懂有关概念
1. 面向对象程序设计的基本概念
面向对象(O-O)程序设计是一种新的程序设计范型。这种范型的主要特征是:
程序=对象+消息
面向对象程序的主要结构特点是:
第一,程序一般由类的定义和类的使用两部分组成,在主程序中定义对象并规定它们之间传递消息的规律;
第二,程序中的一切操作都是通过向对象发送消息来实现的,对象接收到后,启动有关方法完成相应操作。
第三,类由继承关系产生相互间的联系。
2. 对象是现实世界的一个实体,其特性是:
(1) 每一个必须有一个名字以区别于其他对象;
(2) 用属性(或叫状态)来描述它的某些特征;
(3) 有一组操作,每一个操作决定对象的一种行为。
(4) 对象的操作可以分为两类:一类是自身所承受的操作,一类是施加于其他对象的操作。
类是:一组具有共同的属性特征和行为特征的对象的抽象。
类与对象的关系是抽象和具体的关系。
3. 面向对象系统的特征是:封装性、继承性和多态性
(1). 将数据结构和作用于数据结构上的操作组成一个实体,数据的表示方式和对数的操作细节被隐藏起来,用户通过操作接口对数据进行操作。这就是数据的封装。
(2). 继承机制允许派生类继承基类的数据和操作(即数据成员和成员函数),也就是说,允许派生类使用基类的数据和操作。同时派生类还可以增加新的操作和数据。
从继承源上分,继承分为单继承和多继承。
(3). 面向对象系统的多态性是指不同的对象收到相同的消息时产生多种不同的行为方式。
重载的概念
4. 新的I/O流
cin是标准输入流,在程序中用于代表标准输入设备,即键盘。运算符“>>”表示向右
cout是标准输出流,在程序中用于代表标准输出设备,即屏幕。运算符“<<”表示向左
使用cin或cout进行I/O操作时,在程序中必须嵌入头文件iostream.h
5. new和delete
6. 引用
引用可为变量起别名,它主要用作函数参数以及函数的返回类型。有变量的引用、参数引用和返回值引用。
7. 类的定义
clsaa 类名 { private: (可缺省)
私有数据成员和函数成员
protected:
保护段数据成员和函数成员
public:
公有数据成员和函数成员
};
成员函数的定义
第一种方式是在类定义中只给出成员函数的原形,而成员函数体在类的外部定义。
第二种方式是将成员函数定义在类的内部,即定义为内置函数。
(1) 隐式定义
(2) 显式定义
8.对象中成员的访问
不论是数据成员,还是成员函数,只要是公有的,就可以被外部函数直接访问,访问的一般格式是:
对象名. 数据成员名 或 对象名. 成员函数名(实参表) 外 部函数不能引用对象的私有成员
类成员的访问属性
类的公有成员不但可以被类中成员函数访问,还可以在类的外部通过类的对象进行访问。类的私有成员只能被类中成员函数访问,不能在类的外部通过类的对象进行访问。
9. 构造函数的特点:
(1) 构造函数的名字必须与类名相同。
(2) 构造函数可以有任意类型的参数,但不能具有返回类型。
(3) 定义对象时,编译系统会自动地调用构造函数。
(4)构造函数也是成员函数,函数体可写在类体内,也可写在类体外。
(5)构造函数被声明为公有函数,但它不能象其他成员函数那样被显式地调用,它是在定义对象的同时被调用的。
10. 析构函数也是特殊成员函数,用于释放对象。
(1) 析构函数与构造函数名字相同,但它前面必须加一个波浪号(~)。
(2) 析构函数没有参数,也没有返回值,而且不能重载,因此在一个类中只能有一个析构函数。
(3) 当撤消对象时,编译系统会自动地调用析构函数。
11. 友元:不属于任何类的一般函数,另一个类的成员函数,整个的一个类。
(1) 友元函数
不属于任何类的一般函数
(2) 友元成员
该函数是另一个类的成员函数,前加上 friend表示该另类的成员函数,又是本类的友元成员。
(3). 友元类
在类内说明一个类(该类前面已定义),前加上 friend表示该类是本类的友元类。友元类的所有成员函数可以访问它自己类私有成员又可本类的私有成员
12. 派生类的定义
基类:
class 类名
{
类的内容
};
声明派生类:
class 派生类名 : 继承方式 基类名
{
//派生类新增的数据成员和函数成员
};
继承方式可为公有继承(用public)、私有继承(用private或缺省)和保护继承(用protected)
13. 基类成员在派生类中的访问属性(重点)
14. 派生类对基类成员的访问规则(重点)
15. 派生类的构造函数和析构函数
(1) 派生类的构造函数和析构函数执行顺序
当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;当撤消派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。
(2). 派生类的构造函数和析构函数的构造规则
一般格式为:
派生类名(参数总表):基类名(参数表)
{
//派生类新增成员的初始化语句
}
其中基类构造函数参数,来源于派生类的构造函数的参数总表,也可以用常数值。
16. 编译时的多态性与运行时的多态性
静态联编(前期联编)
静态联编要求在程序编译时就知道调用哪个函数,就决定如何实现某一动作。
动态联编(后期联编、滞后联编)
一直要到程序运行时才能确定调用哪个函数。系统在运行时才动态完成的联编。
静态联编支持的多态性称为编译时多态性,也称静态多态性。在C++中,编译时多态性是通过函数重载和运算符重载实现的。
动态联编支持的多态性称为运行时多态性,也称动态多态性。在C++中,运行时多态性是通过继承和虚函数来实现的。
函数重载:类外的一般的函数、成员函数和构造函数都可以重载
17.运算符重载:除了可以对函数重载外,还可以对大多数运算符实施重载。
外部函数 类的友元函数 是类的成员函数
成员运算符函数定义的语法形式
成员运算符函数的原型在类的内部声明格式为:
class X{
//...
返回类型 operator 运算符(形参表);
//...
};
18.引入派生类后的对象指针
引入派生类后,由于派生类是由基类派生出来的,因此指向基类的指针和指向派生类的指针是相关的。
(1)基类的指针可以指向它的公有派生类的对象。但不允许指向它的私有派生类的对象。
(2)派生类的指针不允许指向它的基类的对象。
(3)基类的指针指向它的公有派生类的对象时,只能用它来直接访问派生类中从基类继承来的成员,而不能直接访问公有派生类中定义的新成员。
19. 模板的概念
(1).函数模板与模板函数
所谓函数模板,就是写一个函数模子,用这个模子套印出许多功能相同,参数类型和返回类型不同的函数。模板函数:函数模板实例化后的具体函数。
(2) 类模板和模板类
类模板 (也称为类属类或类生成类)是:允许用户为类定义一种模子,使得类中的某些数据成员,某些成员函数的参数或者返回值,能取任意数据类型
20. 文件的输入输出
在含有文件操作的程序中,必须有如下的预处理命令: # include <fstream.h>
复习思考题、即考试的A、B、C、D选择题和填空题
一、分清下面的概念,那些是正确的,那些是错误的
1. 面向对象程序的主要结构特点之一
√程序一般由类的定义和类的使用两部分组成。程序一般由函数定义和函数的使用两部分组成。
程序一般由变量的定义和变量的使用两部分组成。程序一般由对象的定义和对象的使用两部分组成。√程序中的一切操作都是通过调用函数来实现的。程序中的一切操作都是通过定义函数来实现的。√程序中的一切操作都是通过向对象发送消息来实现的。程序中的一切操作都是通过定义类来实现的。
2.对象是现实世界中的一个实体,其特性
√每个对象必须有一个名字。 有属性描述。 有一组操作。√必须有一个关键字,以示区别。
√定义对象时会自动调用构造函数。 一定要定义一个构造函数。 一定要有二个以上数据。
3.面向对象系统的特性是
√封装性 √继承性 √多态性 完整性 唯一性 二义性 可重用性 安全性
4.类和对象之间的关系是
定义和被定义的关系。调用和被调用的关系。类即是对象数组。√抽象和具体的关系。
√类型和变量之间的关系。型和值的关系。结构类型和结构体的关系。指针和所指的对象的关系。
5.类的概念是
对同一类整型数据的集合。√对一组具有共同的属性特征和行为特征的对象的抽象。类即是对象数组。 各种对象的集合。√同一类数据的集合。同一记录的集合。同类函数的集合。现实世界中所有对象的集合。
6.构造函数的特征
√构造函数的函数名与类名相同。构造函数必须说明返回类型。√编译系统会自动调用构造函数。
√构造函数可以重载。构造函数的函数名与类名不相同。程序中要有调用构造函数的语句。
7.析构函数的特征
√一个类中只能定义一个析构函数。析构函数名与类名不同。析构函数的定义只能在类体内
析构函数可以有多个参数。一个类中能定义多个析构函数。√析构函数名与类名相同并加~。
√编译系统会自动调用析构函数。析构函数可以有多个参数
8. 关于成员函数特征的下述描述
成员函数一定是内置函数。√成员函数可以重载。√成员函数可以设置参数的缺省值。√成员函数可以是静态的。√类定义中只给出成员函数的原型,而成员函数在类外定义。√类定义中只给出成员函数的原型,而成员函数在类外定义并在之前加inline。成员函数一定要在类内定义。可在类内定义。
9.下列的各类函数中,不是类的成员函数
构造函数 析构函数 友元函数 拷贝构造函数 √主函数 √一般函数 √标准函数 缺省参数的构造函数
10.友元的作用是什么,一个类的友元可以访问该类的什么
√提高程序的运行效率。加强类的封装性。√实现数据的隐藏性。增加成员函数的种类
√私有成员和公有成员 只能是私有成员 只能是公有成员 成员函数
11.对基类和派生类的关系描述中
派生类是基类的具体化。√派生类是基类的子集。√派生类是基类定义的扩延。派生类是基类的组合。 √无论哪种派生,基类的私有成员不允许派生类的成员函数访问。无论哪种派生,基类的公有成员允许派生类的成员函数访问。√无论哪种派生,基类的保护成员允许派生类的成员函数访问。√无论哪种派生,基类的保护成员不允许派生类的成员函数访问。
12.派生类的对象对它的基类成员中,可以访问的是
√公有继承的公有成员。公有继承的私有成员。公有继承的所有成员。私有继承的公有成员。
私有继承的私有成员。私有继承的所有成员。√公有继承的保护成员。私有继承的保护成员。
13.对定义几个重载函数的要求中,错误的是。不可重载的函数的是。
√要求参数的个数不同。要求参数中至少有一个类型不同。要求函数名相同。√要求函数的返回值类型一定不同。
普通的成员函数。友元函数。外部函数。 √析构函数
14.可定义作运算符重载函数的是
构造函数。 √成员函数。√友元函数。√类以外的函数。析构函数。无返回值的函数。
15.设置虚基类的目的是,对虚基类的论述,正确的是
简化程序。√消除二义性。提高运行效率。减少目标代码。
定义虚基类时加virtual。 √定义派生类时,在基类名前加virtual。在基类的成员函数前加virtual。在派生类名前加virtual。
16.不能重载运算符
&& √:: [ ] new √? : ++ ( ) delete
17.关于动态联编的描述,动态联编称为运行时的多态性是通过什么来实现的。
√动态联编是以虚函数为基础的。√动态联编是在运行时确定所调用的函数的。动态联编调用的函数,是用对象的指针或对象引用所指的函数。动态联编是在编译时确定操作函数的。函数重载和运算符重载。 √继承和虚函数。 运算符重载。 函数重载。
18.关于虚函数的描述,抽象类论述
虚函数是一个static类型的成员函数。 虚函数是一个非成员函数。 √虚函数是在基类中用virtual 说明,派生类中重新定义的函数。派生类的虚函数与基类的虚函数具有不同的参数个数和类型。
√如果一个类至少有一个纯虚函数,那么该类为抽象类。√抽象类只能用作其他类的基类,不能建立抽象类对象。√抽象类可以用来定义指针。抽象类可以作为某个函数的返回类型。
19. 对虚基类正确的论述
定义基类时加virtual。 √ 定义派生类时,在基类名前加virtual。成员函数前加virtual。 在派生类名前加virtual。
20.进行文件操作时需要包含的文件,C++用cout 和 cin 进行输出/输入操作时需要包含文件。
√iostream.h fstream.h stdio.h stdlib.h string.h math.h
21.在定义类时,第一个保留字。 (class)
22.将数据结构和作用于数据结构上的操作组成一个实体,数据的表示方式和对数据的操作细节被隐藏起来,这是面向对象程序设计的 (封装性)。而函数重是 (多态性)。
23.C++中类的定义内部,英文private段 ,protected 段,public段(私有段 保护段 公有段 )
24. 定义了类A,在主函数中如出现: A *p, obj, ob[10]; 的语句。(则p是对象指针、obj是对象、ob是对象数组。)
25.C++的运算符:<< >> new delete (输入 输出 申请 释放)
26. 在C++定义的类中,成员可分为二类,有三个段。(数据 函数 私有 公有 保护)
27. 在一个类定义中,可以声明友元,友元可以是三种友元。(友元函数 友元成员 友元类)
28. C++中,函数说明为void fun(int &i)的引用叫,函数说明为void &fun(int i)的引用叫。
( 参数引用 返回值引用 )
29. 继承机制允许派生类继承基类的什么,同时,派生类还可以增加新的什么。
( 数据和操作 数据和操作 )
30.一个类模板允许用户为类定义什么?使得类中的某些数据成员、某些成员函数的参数或返回值,能取什么类型?模板是实现代码重用机制的一种工具,函数模板的实例化、类模板的实例化分别称为 (一个模式(子) 任意数据类型 分别称为模板函数 、模板类)
二、阅读程序写运行结果、程序填空题(对照习题)
1. 引用和函数调用
2. 派生和继承的应用
3. 派生类的构造函数和析构函数执行顺序
4.运算符重载
复习思考题
1.
#include <iostream.h>
void main( )
{ int &index(int i, int b[] );
int a[]={1,3,5,7,9},j;
cout<<a[2]<<” ”;
j=index(2,a)=25;
cout<<j <<” ”<<a[2]<<endl;
}
int &index(int i, int b[] )
{
return b[i];
}
答案: 5 25 25
2.
#include <iostream.h>
void fun1(int m, int n)
{ m=11; n=24; }
void fun2(int &m, int &n)
{ m=10; n=20; }
void main( )
{ int a=15,b=30;
cout<<"a="<<a<<" b="<<b<<endl;
fun1(a,b);
cout<<"a="<<a<<" b="<<b<<endl;
fun2(a,b);
cout<<"a="<<a<<" b="<<b<<endl;
fun2(a,b);
cout<<"a="<<a<<" b="<<b<<endl;
}
答案: a=15 b=30
a=15 b=30
a=10 b=20
a=10 b=20
3.
#include <iostream.h>
class point { int x, y;
public:
point( int x1=0, int y1=0) {
x=x1; y=y1;
}
void print();
};
void point::print() {
cout<<"x="<<x<<" y="<<y<<endl;
}
void print(point p) {
p.print();
}
void main()
{ point p1(10,20),p2(30),p3,*p;
p=&p1;
p->print();
p2.print();
print(p3);
}
答案: x=10 y=20
x=30 y=0
x=0 y=0
4.
#include <iostream.h>
class point { int x, y, d;
public:
point( int x1=0, int y1=0) {
x=x1; y=y1; d=x*x+y*y;
}
void print(){
cout<<"x="<<x<<" y="<<y<<” dist=”<<d<<endl;
}
};
void main()
{ point p1(1),p2(2,3),*p;
p=&p1;
p->print();
p2.print();
}
答案: x=1 y=0 dist=1
x=2 y=3 dist=13
5.
#include <iostream.h>
#include <string>
class strcl { char *str;
public:
strcl(){cout<<"现在进入了strcl类的缺省构造函数"<<endl;}
strcl(char *st) {
cout<<"现在进入了strcl类的构造函数"<<endl;
str=new char[strlen(st)+1];
strcpy(str,st);
}
void show1() { cout<<"name:"<<str; }
};
class girl { strcl name;
int age;
public:
girl():name(){ cout<<"现在进入了girl类的缺省构造函数"<<endl;}
girl(char *st, int n ):name(st) {
cout<<"现在进入了girl类的构造函数"<<endl;
age=n;
}
int show2() {
name.show1(); cout<<" age:"; return age;
}
};
void main()
{ girl g1;
girl g2("zhang_fun", 20);
}
答案:现在进入了strcl类的缺省构造函数
现在进入了girl类的缺省构造函数
现在进入了strcl类的构造函数
现在进入了girl类的构造函数
6.
#include <iostream.h>
class Time { char a[9];
int hours;
int minutes;
int seconds;
public:
Time(int s=0, int m=0, int h=0) {
hours=h;
minutes=m;
seconds=s;
}
void show() {
cout<<"时间: "<<hours<<":"<<minutes<<":"<<seconds<<endl;
}
friend Time operator +(Time t1, Time t2);
};
Time operator +(Time t1, Time t2) {
Time temp;
temp.hours=t1.hours+t2.hours;
temp.minutes=t1.minutes+t2.minutes;
temp.seconds=t1.seconds+t2.seconds;
if(temp.seconds>60){ temp.seconds=temp.seconds-60;
temp.minutes++; }
if(temp.minutes>60){ temp.minutes=temp.minutes-60;
temp.hours++; }
if(temp.hours>=24) temp.hours=temp.hours-24;
return temp;
}
void main()
{ Time T, T1(20,23,21), T2(10,25,15), T3(5,10,15);
T=T1+T2;
T.show();
T=T+T3;
T.show();
}
答案: 时间: 12:48:30
时间: 3:58:35
7.下面的程序定义一个类samp,有三类数据成员和一个构造函数和一个函数成员,填充程序缺少部分,使其变成完整的C++程序。
#include <iostream.h>
class samp{
int a;
protected:
int b;
public:
int c;
(1) (int n, int m ) //构造函数
{ a=n; (2) ; c=a+b; }
int ⑶ (int i){
if (i==1) return a;
else if(i==2) return b;
else return 0;
}
};
void main ( )
{ samp obj(20,30);
cout << (4) << endl; //输出a
cout << obj.getab(2) << endl; //输出b
cout << (5) << endl; //输出c
}
答案: ⑴. samp ⑵. b=m; ⑶. getab ⑷. obj.getab(1) ⑸. obj.c
8.下面的程序包含了日期(Date)类的声明,要求设计一个Brithtime类,它继承了Date类,并且还有一项出生孩子的名字Childname,主程序显示了一个小孩的名字和出生日期。请补足Brithtime类的public部分。
#include <iostream.h>
#include <string.h>
class Date{
protected:
int month,day,year;
public:
Date(int m, int d, int y)
{ month=m; day=d; year=y; }
void display()
{ cout<<month<<"/"<<day<<"/"<<year<<endl;
}
};
class Brithtime: public Date{
protected:
char *Childname;
public:
⑹ // 补充Brithtime类的public部分
};
void main( )
{ Brithtime ob("张三",10,1,2004);
ob.display();
}
答案: ⑹. Brithtime(char *p ,int m, int d, int y):Date(m,d,y)
{ Childname=new char[strlen(p)+1];
strcpy(Childname,p);
}
void display()
{ cout<<"姓名:"<<Childname<<"\n";
cout<<"出生日期:"; Date::display();
}
三、程序设计题
1.C语言复习及C++基础知识
2.定义类、成员函数及构造函数的习题
思考题、来自《VC++6.0面向对象程序设计实验提纲》
1. 下面是一个C程序,改写它,使它采用C++风格的I/O语句。
#include <stdio.h> ← #include <iostream.h>
void main()
{ int a,b,d,min;
printf("输入两个整数:"); ← cout<<"输入两个整数:";
scanf(”%d%d”,&a,&b); ← cin>>a; cin>>b;
min=a>b?b:a;
for(d=2;d<=min;d++)
if((a%d==0)&&(b%d==0))break;
if(d > min)
printf("没有公约数!\n"); ← cout<<"没有公约数!\n";
else
printf("最小公约数是:%d\n",d); ← cout<<"最小公约数是:"<<d<<endl;}
2. 从键盘输入二个任意大小的数,在屏幕上从小到大输出这二个数。
#include <iostream.h>
void main()
{ int a, b, c;
cin>>a; cin>>b;
if(a>b) { c=a; a=b; b=c; }
cout<<a<<” ”<<b<<endl;
}
3. 定义一个基类圆circle,私有段有圆的半径,公有段有构造函数,能显示圆面积等。定义派生类ex_square为圆的外切正方形,有构造函数,能显示正方形面积。在主函数中定义外切正方形对象,其圆半径为10,显示两者面积。
答案:
#include <iostream.h>
class circle { float r; //声明一个圆类
public:
circle (float x=0) { r=x; } //构造函数
void area1 ( ) //函数area ( ) 显示圆面积
{ cout<< "圆面积是:"<< 3.14*r*r<<endl; }
float getr() { return r; }
};
class ex_square : public circle { //派生一个圆外切正方形类
public:
ex_square (float x) : circle (x){ } //构造函数
void area2 ( ) //函数area ( ) 显示正方形面积
{ cout << "外切正方形面积是:"<<4*getr()*getr()<<endl; }
};
void main( )
{ ex_square ob(10);
ob.area1();
ob.area2();
}
4. 定义一个基类长方形base,私有段有长a和宽b,公有段有构造函数,能显示长方形面积等。定义以该长方形为底面积的派生类长方体cuboid,有高h,有构造函数,能显示长方体体积。在主函数中定义长方体对象,其长、宽、高分别为10,20,5,显示出长方体体积和长方形底面积。
答案:
#include <iostream.h>
class base { float a,b; //声明长方形
public:
base (float a1=0, float b1=0) {
a=a1; b=b1;
}
void area ( ) //函数area ( ) 显示长方形面积
{ cout<< "长方形面积是:"<< a*b <<endl; }
float getr() { return a*b; }
};
class cuboid : public base { //以该长方形为底的派生类长方体
float h;
public:
cuboid (float a1, float b1, float h1 ) : base (a1,b1){
h=h1;
}
void body ( ) //函数body ( ) 显示长方体体积
{ cout << "长方体体积是:"<<h*getr()<<endl; }
};
void main( )
{
cuboid ob(10,20,5);
ob.area();
ob.body();
}
5. 定义一个基类建筑物building,私有段有楼房层数fr,房间数r,楼房总面积m,有构造函数。定义派生类住宅楼house,有卧室数量 br,浴室数量 dr,有构造函数,能显示住宅楼所有数据。定义派生办公大楼offic,灭火器数量mr ,电话数量tr,有构造函数,能显示办公大楼所有数据。在主函数中定义住宅楼对象,其楼房层数、房间数、楼房总面积、卧室数量和浴室数量分别为 10,200,300000,500,300。定义办公大楼对象,其楼房层数、房间数、楼房总面积、灭火器数量和电话数量分别为18,560,2500000,1500,600。
答案:
#include <iostream.h>
class building{
protected: int fr; int r; double m;
public:
building(int a, int b, double x){ fr=a; r=b; m=x; }
};
class house : public building {
private: int br; int dr;
public:
house(int a, int b, double x, int c, int d):building(a,b,x){ br=c; dr=d; }
void show()
{ cout << "楼房层数 :"<<fr<<endl;
cout << "房间数 :"<<r<<endl;
cout << "楼房总面积:"<<m<<endl;
cout << "卧室数量 :"<<br<<endl;
cout << "浴室数量 :"<<dr<<endl;
}
};
class offic : public building {
private:
int mr; int tr;
public:
offic(int a, int b, double x, int c, int d):building(a,b,x){ mr=c; tr=d; }
void show()
{ cout << "楼房层数 :"<<fr<<endl;
cout << "房间数 :"<<r<<endl;
cout << "楼房总面积:"<<m<<endl;
cout << "灭火器数量:"<<mr<<endl;
cout << "电话数量 :"<<tr<<endl;
}
};
void main()
{ house ob1(10,200,300000,500,300);
offic ob2(18,560,2500000,1500,600);
cout <<"住宅楼"<<endl;
ob1.show();
cout <<"\n办公大楼"<<endl;
ob2.show();
}
面向对象C++程序设计复习 第15页 共15页
展开阅读全文