面向对象程序设计C++第四章
C++面向对象程序设计课后题答案

面向对象程序设计课后题答案第二章C++概述【2.6】D【2.7】D【2.8】A【2.9】A【2.10】B【2.11】A【2.12】C【2.13】B【2.14】D【2.15】C【2.16】D【2.17】C【2.18】程序的运行结果:101【2.19】程序的运行结果:10 10【2.20】程序的运行结果:1020【2.22】编写一个C++风格的程序,用动态分配空间的方法计算Fibonacci数列的前20项并存储到动态分配的空间中。
#include <iostream.h>int main(){int *p,i;p[0]=1;p[1]=1;for(i=2;i<20;i++){p[i]=p[i-1]+p[i-2];}for(i=0;i<20;i++){cout<<p[i]<<endl;}return 0;}【2.23】编写一个C++风格的程序,建立一个被称为sroot()的函数,返回其参数的二次方根。
重载sroot()3次,让它返回整数、长整数与双精度数的二次方根。
#include <iostream.h>#include<math.h>double sroot(int m){return sqrt(m);}double sroot(long m){return sqrt(m);}double sroot(double m){return sqrt(m);}int main()cout<<"sroot(145)="<<sroot(145)<<endl;cout<<"sroot(123456)="<<sroot(123456)<<endl;cout<<"sroot(1.44)="<<sroot(1.44)<<endl;return 0;}【2.24】编写一个C++风格的程序,解决百钱问题:将一元人民币兑换成1、2、5分的硬币,有多少种换法?#include <iostream.h>int main(){int k=0;for(int i=0;i<=20;i++){for(int j=0;j<=50;j++){if(100-5*i-2*j>=0){k++;}}}cout<<"将一元人民币兑换成1、2、5分的硬币,共有"<<k<<"种换法"<<endl;return 0;}【2.25】编写一个C++风格的程序,输入两个整数,将它们按由小到大的顺序输出。
《面向对象程序设计》第04章在线测试

《面向对象程序设计》第04章在线测试《面向对象程序设计》第04章在线测试剩余时间:58:55答题须知:1、本卷满分20分。
2、答完题后,请一定要单击下面的“交卷”按钮交卷,否则无法记录本试卷的成绩。
3、在交卷之前,不要刷新本网页,否则你的答题结果将会被清空。
第一题、单项选择题(每题1分,5道题共5分)1、如果在类B 中定义友元,其中正确的是:A、class B { friend int fun(A*, B&);};B、class B { friend int fun(A*, B*);};C、class B { friend int fun(A&, B&);};D、class B { friend int fun(A&, B*);};2、下面的语句中能将类B 定义为类A的友元类的是()A、friend class B;B、class A{ friend B};C、class A{ friend class B;};D、class friend B class A;3、关于友元的说法正确的是()A、友元关系可以继承B、友元关系是双向的C、友元关系不可以传递D、友元关系可以取消4、下面对于友元函数描述正确的是A、友元函数的实现必须在类的内部定义B、友元函数是类的成员函数C、友元函数破坏了类的封装性和隐藏性D、友元函数不能访问类的私有成员5、一个类的友元函数或友元类能够通过成员操作符访问该类的()A、私有成员B、保护成员C、公有成员D、所有成员第二题、多项选择题(每题2分,5道题共10分)1、下面关于友元函数正确的说法是()A、在类中用关键词friend声明友元函数B、友元函数说明的位置只能在类的public区C、友元函数的定义只能放在类的外部D、友元函数不是类的成员函数2、定义类B的构造函数为类A的友元函数的语句是()A、class A { friend B();};B、class A { friend B::B();};C、class A { friend void B::B();};D、class A { friend double B::B();};3、关于友元函数的说法正确的是()A、友元函数可以是普通函数,可以是其他类的成员函数,也可以是本类的成员函数B、友元函数可以访问多个类的私有成员和保护成员C、在调用友元函数的时候需要使用“.”运算符D、如果友元函数是某个类的成员函数,在定义这个友元函数的时候要使用类前缀。
第四章 面向对象2.0

对象的创建与使用
IBM Software Group
IBM Software Group
属性和方法的引用
引用成员变量 对象名.成员变量名 引用方法 对象名.方法名(参数列表)
IBM Software Group
类和对象的示例
• 编写一个Box类,它有三 个属性length,width,height 和一个用于求体积 的方法volume(),这个方法返回类型为void,也不带参数。求它的体积。 • 在上题的基础上改进一下,把volume()改成带double返回类型。 • 再改进一下,把volume()改成带double返回类型和三个参数。
IBM Software Group
package和import语句
IBM Software Group
package和import语句总结
IBM Software Group
IBM Software Group
IBM Software Group
IBM Software Group
IBM Software Group
IBM Software Group
面向对象设计的三个基本特征
3. 多态:是指一个程序中同名的方法共存的情况,调用者只需使用同一个方法名, 系统会根据不同情况,调用相应的不同方法,从而实现不同的功能。多态性又被 称为“一个名字,多个方法”。
IBM Software Group
抽象和封装
• 前面已讲过,抽象和封装主要涉及到类和对象及其组成元素- 属性和方法。那么, 什么是类,什么是对象?它们各自是如何定义的? 类和对象的属性及方法又是如何定义并使用的? 对象之间是如何通讯的? 属性、局部变量与方法的参数之间的作用范围是如何划分的? 构造函数有什么作用?它有哪些形式?
第四章 面向对象程序设计基础

OOA
OOD
OOP
面向对象的基本概念——对象 对象 面向对象的基本概念
对象具有两方面的含义:
在现实生活中
客观世界的实体
在计算机程序中
程序中对象就是一组变量和相 关方法的集合,其中变量表明 对象的状态,方法表明对象所 具有的行为。
import语句 语句
引入包中的类。 import java.io.File; 引入整个包。 import java.io.*; 在同一包中的类可以互相引用,无需 import语句。
访问控制修饰符
修饰符 public protected default private 任何地方 √ 子类中 √ √ 同包中 √ √ √ 本类中 √ √ √ √
第四章 面向对象程序设计基础
面向对象编程基础——程序语言的发展 程序语言的发展 面向对象编程基础
面向机器( 面向机器 机器语言、汇编语言) – 汇编是对机器语言的抽象。 – 可读性、可维护、移植性差;效率高。 面向过程 – 面向过程语言是对汇编的抽象。 – 核心:算法 + 数据结构 – 缺陷: 随着应用程序的规模扩大,操作与数据分离所带来的维护工作 量越来越大 不适用于GUI界面、事件驱动编程 是对现实问题的抽象。 面向对象 是对现实问题的抽象。
void brake() { … } void speedUp() {…} void slowDown() { … }
抽象数据类型
面向对象与面向过程区别
面向过程:第一步干什么,第二步干什 么,第三。。。。。 面向对象:一共有几个对象,对象之间 都是什么关系? 面向对象的基本思想是:从现实世界中 客观存在的事物出发来构造软件系统. 并在系统的构造中尽可能运用人类的自 然思维方式.
面向对象程序设计 四

• 4.1 派生类的概念 • 4.2 派生类的构造函数和析构函数 • 4.3 调整基类成员在派生类中的访问属性的 其他方法 • 4.4 多重继承 • 4.5 赋值兼容规则
第四章 派生类与继承
继承允许在既有类的基础上创建新的类,新类可以从 一个或多个既有类中继承数据和函数,而且可以重新定义 或加进新的数据和函数。 假设有两个类---类A 和类B,若类B继承类A,则类B 具有类A的基本特性(包括数据和程序代码) A (基类或父类) B (派生类或子类)
(3)基类中的保护成员:
当继承方式为公有继承时,基类中的保护成员在派生类中为保护成员 当继承方式为私有继承时,基类中的公有成员在派生类中为私有成员 当继承方式为保护继承时,基类中的公有成员在派生类中为保护成员
4.1 派生类的概念
4.1.4 派生类对基类成员的访问规则 派生类对基类成员的访问形式: (1)内部访问:由派生类中新增成员对基类继承来的成员的访问。 (2)对象访问:在派生类外部,通过派生类的对象对从基类继承来的 成员的访问。 派生类对基类成员的访问规则 (1)私有继承的访问规则 (2)公有继承的访问规则 (3)保护继承的访问规则
4.2 派生类的构造函数和析构函数
在类间实现继承时,虽然派生类继承了基类的成员,从而实现了 原代码的重用,但由于基类的构造函数和析构函数不能被继承 基类的构造函数和析构函数不能被继承,因此 基类的构造函数和析构函数不能被继承 在派生类中,如果对派生类新增的成员进行初始化,就需要加入派生 类的构造函数。 同时,对所有从基类继承下来的成员的初始化工作,还是由基类 的构造函数来完成,但是我们必须在派生类中对基类的构造函数所需 必须在派生类中对基类的构造函数所需 要的参数进行设置。 要的参数进行设置 同样,对撤销派生类对象时的扫尾、清理工作也需要加入新的析 构函数来完成。
面向对象程序设计第四章

4.1 抽象与封装
封装就是将数据的表现方式和对数据的操作细节隐藏 起来,用户可以通过接口对数据进行操作,而不必要 知道数据是如何表示的,怎么对数据操作的这些细节 封装是面向对象的基本特征之一 变速箱变速、汽车驱动、汽车转向等原理都被封装在 汽车内部了,提供给驾驶员的只是一个接口。驾驶员 只需要踩下油门、转动方向盘就可以上路了 我们不必要知道录音机、MP3播放器、电视机遥控器 等内部细节,只需要知道按下哪个键可以播放、停止 即可
类成员包括成员函数和数据成员两类。 包含可执行代码的成员统称为该类的成员函数。 类的成员函数包括:方法、属性、事件、索引 器、运算符和构造函数。 类的数据成员包含类要处理的数据,可以是常 量和字段。
4.3 对象
4.3.1 创建对象 使用new运算符,可以创建对象,即类的实例。对象 是一个引用类型的变量。 对象的创建形式: 类名 对象名 = new 类名(参数); Goods cloth = new Goods(10); 使用new运算符创建对象,并调用类的构造函数完成 对象的初始化工作。也可以分两步创建对象: Goods cloth ; cloth = new Goods(10);
protected
internal protected internal
定义保护成员。成员可以从定义它的类内部,以及派 生类访问
定义内部成员。成员只能从当前程序集中访问 定义内部保护成员。成员在当前程序集、定义它的类 内部和派生类访问
4.7.1 使用传统的读写方法进行封装
在程序中,可以使用传统的读写方法封装私有 数据。通常先定义私有字段,然后定义一个读 私有字段的方法和一个修改字段的方法。如果 想访问类中封装的私有数据,只能通过读写方 法完成,这样可以保证类中封装数据的完整性
面向对象编程技术第四章

说明:
3.保护类型与private类似,其差别表现在继承与派生时对派 生类的影响不同,在第七章介绍。
下页 例子
•面向对象编程技术第四章
class circle {
public: circle::circle(int r)
{ radius=r;
}
构造函数,后面介绍
int area()
1. 成员函数分类 (1)构造函数与析构函数
2.不能在定义时初始化赋值
(2)其他成员函数
定义成员时并不分配存储空间, 如 int hour=0
2. 在类中说明原形,在类外给 出函数体实现,并在函数名前 使用类名加以限定。也可以直 接在类中给出函数体
允许声明重载函数和带缺省形
参值的函数
建议定 义在类
•面向对象编程技术第四章
}
•面向对象编程技术第四章
时钟类的成员(数据成员与函数成员声明)
class Clock
{private:
数据成员
int Hour, Minute, Second;
public:
void SetTime(int NewH, int NewM, int
NewS); void ShowTime( ) ;
{
return (int)3.14*radius*radius;
ERROR! 不允
} void circle_prt()
许访问私数 据!如何解决?
{
cout<<"the private radius is:"<<radius<<endl;
} private:
int radius;
第四章 面向对象(上)

4.3 类的域(属性)与方法(操作)
Java中类包括域和方法两部分
域:即属性也称数据成员,是事特物静态特征 的抽象,可以是基本数据类型的数据或数组, 也可以是某一个类的对象
方法:即操作也称成员方法,是事物动态特征 的抽象,用于处理该类的数据
类的基本定义格式如下:
[修饰符] class 类名 [extends 父类] [implements 接口名] { 成员变量基本数据类型或某个类的对象 成员方法函数 }
类与对象
对象是对客观事物的抽象 类是对对象的抽象,在语言中是一种抽象的数 据类型。 它们的关系是,对象是类的实例,类是对象的 模板。
对象引用
类类型变量称为引用变量,它们并不直接保留 对象,只是保留对象的地址,而不是拥有对象 本身,通过引用变量即可以得到一个对象。 所有对象总是且只能通过内存引用访问,这种 方式称为间接寻址。
第四章 类与对象(上)
主要内容
4.1 面向对象技术 4.2 抽象、 类、对象及引用 4.3 类的域与方法 4.4 对象 4.5 构造方法 4.6 类成员属性和方法的非访问修饰符 4.7 包(Package)
4.1 面向对象技术
4.1.1 面向过程与面向对象的比较 面向过程程序设计方法
过程化程序设计先确定算法,再确定数据结构 程序=算法+数据结构 缺点
类成员方法
[修饰符] 返回值类型 方法名(参数列表)
[throws 例外名1,例外名2,…] { 局部变量声明;
语句序列;
}
类成员方法
局部变量
局部变量在某一个语句(如for语句)或代码块 (如方法体)中声明,作用域是声明该变量的 语句或代码块 局部变量使用前必须初始化
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3
函数的重载
所谓函数的重载是指完成丌同功能的函数可以具有相同的函
数名。 C++的编译器是根据函数的实参来确定应该调用哪一个函数 的。
int fun(int a, int b) { return a+b; }
void main(void) { cout<<fun(3,5)<<endl; cout<<fun(5)<<endl; }
c1=(3,4i) c2=(5,-10i) c1+c2=(8,-6i)
9
4.2 运算符重载方法
共有两种方法 重载为类的成员函数 重载为友元函数
10
重载为类的成员函数
格式如下:
关键字
运算的对象
<类名> operator<运算符>(<参数表>) { 函数体 }
返回类型
函数名
运算的对象
A(float a=0, float b=0){ x=a; y=b; }
a(2,3), b(3,4), c;
c=a+b;
两对象丌能使用+,必须重新定义+
运算符重载就是赋予已有的运算符多重含义。
C++通过重新定义运算符,使它能够用于特 定类的对象执行特定的功能
7
运算符的重载
运算符的重载从另一个方面体现了OOP技术的多态性,丏同
由对象a3调用
A operator +(A &a) { A t; 形参 t.i=i+a.i; return t; }
函数调用: a3=a1+a2; a3=a1.operator+(a2);
由对象a1调用
15
比较
返回值
函数名
总结:
重新定义运算符,由左
A operator +(A &a) { A t; 形参 t.i=i+a.i; return t; }
A operator + (A &);
一起构成函数名。
//重载了类A的“+”运算符
其中:operator是定义运算符重载函数的关键字,它不其后的运算符
11
例子
没有重载运算符的例子
class A { int i; public:A(int a=0) { i=a; void Show(void){ void AddA(A &a, { i=a.i+b.i; }; void main(void) { A a1(10),a2(20),a3; a1.Show (); a2.Show (); // a3=a1+a2; a3.AddA(a1,a2); a3.Show (); }
c1=(3,4i) c2=(5,-10i) c1+c2=(8,-6i)
14
重载运算符与一般函数的比较:
相同:1)均为类的成员函数;2)实现同一功能
返回值 函数名 形参列表 返回值 函数名
void AddA(A &a, A &b) { i=a.i+b.i; } 函数调用: a3.AddA(a1,a2);
18
说明
2、在C++中,允许重载的运算符列于表4.1中。
3、在C++中丌允许重载的运算符列于表13.2。
4、只能对C++中已定义了的运算符迚行重载,而丏,当重
载一个运算符时,该运算符的优先级和结合律是丌能改变的
19
例子
第4章 运算符重载
学习目标
多态性是面向对象程序设计的重要特征之一。它不封装性和继承性构成了面 向对象程序设计的三大特征。这三大特征是相互关联的。封装性是基础,继 承性是关键,多态性是补充,而多态又必须存在于继承的环境之中。• 所谓多态性是指发出同样的消息被丌同类型的对象接收时导致完全丌同的行 为。这里所说的消息主要是指对类的成员函数的调用,而丌同的行为是指丌 同的实现。利用多态性,用户只需发送一般形式的消息,而将所有的实现留 给接收消息的对象。对象根据所接收到的消息而做出相应的动作(即操作)。• 函数重载和运算符重载是简单一类多态性。 运算符重载就是赋予已有的运算符多重含义。 C++中通过重新定义运算符,使它能够用于特定类的对象执行特定的功能, 这便增强了C++语言的扩充能力。•
} cout<<"i="<<i<<endl; } A &b) //利用函数迚行类之间的运算 } 利用函数完成了加法运算
//丌可直接运算 //调用与门的功能函数
用和作对象调用函数
12
例子
class A { int i; public:A(int a=0){ i=a; } void Show(void){ cout<<"i="<<i<<endl; } void AddA(A &a, A &b) //利用函数迚行类之间的运算 { i=a.i+b.i; } A operator +(A &a) //重载运算符+ { A t; t.i=i+a.i; return t; } }; void main(void) 相当于a3=a1.operator+(a2) { A a1(10),a2(20),a3; a1.Show (); a2.Show (); a3=a1+a2; //重新解释了加法,可以直接迚行类的运算 a3.AddA(a1,a2); //调用与门的功能函数 a3.Show (); }
一运算符根据丌同的运算对象可以完成丌同的操作。
为了重载运算符,必须定义一个函数,并告诉编译器,遇到
这个重载运算符就调用该函数,由这个函数来完成该运算符 应该完成的操作。这种函数称为运算符重载函数,它通常是 类的成员函数或者是友元函数。运算符的操作数通常也应该 是类的对象。
8
例4.1
#include <iostream> using namespace std; class Complex {public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} Complex complex_add(Complex &c2); void display(); private: double real; double imag; }; Complex Complex::complex_add(Complex &c2) {return Complex(real+c2.real,imag+c2.imag);} void Complex::display() {cout<<"("<<real<<","<<imag<<"i)"<<endl;} int main() {Complex c1(3,4),c2(5,-10),c3; c3=plex_add(c2); cout<<"c1="; c1.display(); cout<<"c2="; c2.display(); cout<<"c1+c2="; c3.display(); return 0; }
17
4.3 运算符重载的规则
1、当用成员函数实现运算符的重载时,运算符重载函数的参
数只能有二种情况:没有参数或带有一个参数。对于只有一 个操作数的运算符(如++),在重载这种运算符时,通常丌能 有参数;而对于有二个操作数的运算符,只能带有一个参数 。这参数可以是对象,对象的引用,或其它类型的参数。在 C++中丌允许重载有三个操作数的运算符
第5章 继承不派生 第6章 多态性不虚函数 第7章 输入输出流 第8章 C++工具
第4章 运算符重载
4.1什么是运算符重载 4.2运算符重载的方法 4.3重载运算符的规则 4.4运算符重载函数作为类成员函数和友元函数 4.5重载双目运算符 4.6重载单目运算符 4.7重载流插入运算符和流提取运算符 4.8不同类型数据间的转换
8 25
4
int fun (int a) { return a*a; }
4.1 什么是运算符重载
函数的重载 1、定义的重载函数必须具有丌同的参数个数,或丌同的参数
类型。只有这样编译系统才有可能根据丌同的参数去调用丌 同的重载函数。
2、仅返回值丌同时,丌能定义为重载函数。
5
问题的提出
int sum,a=3,b=2; sum=a+b; (int)=(int) + (int) float add, x=3.2, y=2.5; (float)=(float) + (float) add=x+y; char str[4], c1[2]="a", c2[2]="b"; str=c1+c2; (char *)=(char *) + (char *)
面向对象程序设计
山东师范大学教学课件 刘希玉 Email: sdxyliu@ xyliu@
管理与经济学院
School of Management and Economics
第1章 C++的初步知识