第8章 多态性

8-4 请编写一个计数器 Counter类,对其重载运算符“+”。

#include <iostream>
using namespace std;class Counter{private:int cnt;public:Counter(int n){cnt=n;}Counter():cnt(0){ }Counter operator+(const Counter& t){Counter r;r.cnt=cnt+t.cnt;return r;}void display(){cout<<"counter = "<<cnt<<endl;}~Counter(){ }
};int main()
{Counter a(100), b(200),c;c = a + b;c.display();return 0;
}

8-5 编写一个哺乳动物类 Mammal,再由此派生出狗类 Dog,二者都声明 speak()成员函数,该函数在基类中被声明为虚函数。声明一个 Dog 类的对象,通过此对象调用speak 函数,观察运行结果。

#include <iostream>
using namespace std;
class Mammal{public:Mammal(){cout << "Constructor in Mammal.\n";}virtual ~Mammal(){cout << "Destructor in Mammal.\n";}virtual void speak(){cout<<"Mammal speak!\n";}};
class Dog:public Mammal{public:Dog(){cout << "Constructor in Dog.\n";}~Dog(){cout << "Destructor in Dog.\n";}void speak(){cout << "Dog sound wang,wang,wang!\n";}
};
int main()
{Mammal *m = new Dog;m->speak();   //使用虚函数,根据指针指向的类型执行哪种方法 delete m;return 0;
}

8-6 请编写一个抽象类 Shape,在此基础上派生出类 Rectangle 和 Circle,二者都有计算对象面积的函数 getArea()、计算对象周长的函数 getPerim ()。

#include <iostream>
using namespace std;
class shape{
public:shape(){}~shape(){}virtual double getarea()=0;virtual double getperim()=0;
};
class rectangle:public shape{
public:rectangle(double l,double w):pl(l),pw(w){}~rectangle();virtual double getarea(){return pl*pw;}virtual double getperim(){return 2*(pl+pw);}
private:double pl;double pw;
};
class circle:public shape{
public:circle(double r):pr(r){}~circle();virtual double getarea(){return 3.14*pr*pr;}virtual double getperim(){return 2*3.14*pr;}
private:double pr;
};
int main(){shape *sp;sp=new circle(1);cout<<"圆的面积是:"<<sp->getarea()<<endl;cout<<"圆的周长是:"<<sp->getperim()<<endl;delete sp;sp= new rectangle(10,85);cout<<"矩形的面积是:"<<sp->getarea()<<endl;cout<<"矩形的周长是:"<<sp->getperim()<<endl;delete sp;return 0;
}

8-7 对类 Point重载“++”(自增)、“–”(自减)运算符,要求同时重载前缀和后缀的形式。

#include <iostream>
using namespace std;class Counter{private:int cnt;public:Counter(int n = 0){cnt=n;}Counter& operator++(){      //后置单目运算符++cnt++;    return *this;}Counter operator++(int){   //前置单目运算符++Counter t = *this;++(*this);return t;}Counter& operator--(){    //后置单目运算符--cnt--;return *this;}Counter operator--(int){    //前置单目运算符--Counter t = *this;--(*this);return t;}void display(){cout<<"counter = "<<cnt<<endl;}
};int main() {Counter a(100);++++a;a.display();for( int i = 0; i < 100; i++ )a++;a.display();----a;a.display();for( int i = 0; i < 100; i++ )a--;a.display();return 0;
}

其中,前置单目运算符和后置运算符的重载最主要的区别就在于重载函数的形参。语法规定,前置单目运算符重载为成员函数时没有形参,而后置单目运算符重载为成员函数时需要有一个int型形参。

前置方式和后置方式的函数内部的语句可以相同,也可以不同,取决于编程的需要。

运算符重载

通常情况下:

1、单目运算符:

重载为成员函数的话,需要0个参数,重载为友元的时候需要一个参数

2、 双目运算符:

重载为成员函数的话,需要一个参数,重载为友元的时候需要俩个参数

friend Complex operator+(Complex &a, Complex &b);

//operator+(a,b);

const Complex operator+(Complex & another);

//a.operator+(b);

//成员的话 当中自己包含一个this 所以只需要一个参数

3、三目运算符没有重载

8-8 定义一个基类 BaseClass,从它派生出类 DerivedClass。BaseClass 有成员函数fn1(),fn2(),fn1()是虚函数;DerivedClass 也有成员函数 fn1(),fn2()。在主函数中声明一个 Derived C lass的对象,分别用 BaseClass 和 Derived C lass的指针指向DerivedClass的对象,并通过指针调用 fn1(),fn2(),观察运行结果。

#include<iostream>
using namespace std;class BaseClass{public:virtual void fn1(){cout<<"基类的虚函数 fn1()"<<endl;}void fn2(){cout<<"基类的非虚函数 fn2()"<<endl;}  //使用虚函数,会依据指针实际指向的对象类型来决定调用谁的方法,实现动态联编 //不使用虚函数,会根据指针本身的类型(或引用类型)来执行对应的方法,实现静态联编
};
class DerivedClass:public BaseClass{public:void fn1(){cout<<"派生类的函数 fn1()"<<endl;}void fn2(){cout<<"派生类的函数 fn2()"<<endl;}
};
int main()
{DerivedClass d;d.fn1();d.fn2();BaseClass *p1 =&d;p1->fn1();p1->fn2();DerivedClass *p2=&d;p2->fn1();p2->fn2();return 0;
}

8-10 编写程序定义类 Point,有数据成员 x,y,为其定义友元函数实现重载“+”。

#include <iostream>
using namespace std;class Point{private:int x,y;public:Point(){x=0,y=0;}Point(int a,int b){x=a;y=b;}friend Point operator+(Point& c,Point& d);void display(){cout<<"("<<x<<","<<y<<")"<<endl;}
};
Point operator+(Point& c,Point& d)
{Point r;r.x=c.x+d.x;r.y=c.y+d.y;return r;      //注意返回的类型
}int main() {Point p1(1,2), p2(-1,1), p3;p1.display();p2.display();p3 = p1 + p2;cout<<"p1+p2=";//若写为<<p3.display(),则会出现错误提示,因为没有定义重载运算符<<p3.display();return 0;
}

8-11 在例 8-6 的基础上,通过继承 Rectangle 得到一个新的类 Square,然后在 Shape 中增加一个函数 int getVertexCount() const用来获得当前图形的顶点个数。用以下几种方法分别实现,并体会各自的优劣。
(3)将 Shape::getVertexCount声明为纯虚函数,在派生类中给出具体实现。

#include <iostream>
using namespace std;
class Shape{
public:Shape(){}~Shape(){}virtual double getarea()=0;virtual double getperim()=0;virtual int getVertexCount()const=0;
};class Circle:public Shape{
public:Circle(double r):pr(r){}~Circle();double getarea(){return 3.14*pr*pr;}double getperim(){return 2*3.14*pr;}virtual int getVertexCount()const{return 0;}
private:double pr;
};class Rectangle:public Shape{
public:Rectangle(double l,double w):pl(l),pw(w){}~Rectangle();virtual double getarea(){return pl*pw;}virtual double getperim(){return 2*(pl+pw);}virtual int getVertexCount()const{return 4;}
protected:double pl;double pw;
};class Square:public Rectangle{
public:Square(float len):Rectangle(len,len){}~Square(){}virtual double getarea(){return pl*pw;}virtual double getperim(){return 2*(pl+pw);}virtual int getVertexCount()const{return 4;}
};int main(){Shape *sp;sp=new Circle(1);cout<<"圆的面积是:"<<sp->getarea()<<endl;cout<<"圆的周长是:"<<sp->getperim()<<endl;cout<<"圆的顶点个数是:"<<sp->getVertexCount()<<endl;cout<<endl; delete sp;sp= new Rectangle(10,85);cout<<"矩形的面积是:"<<sp->getarea()<<endl;cout<<"矩形的周长是:"<<sp->getperim()<<endl;cout<<"长方形的顶点个数是:"<<sp->getVertexCount()<<endl;cout<<endl; delete sp;sp= new Square(6);cout<<"正方形的面积是:"<<sp->getarea()<<endl;cout<<"正方形的周长是:"<<sp->getperim()<<endl;cout<<"正方形的顶点个数是:"<<sp->getVertexCount()<<endl;cout<<endl; delete sp;return 0;
}
  • 其中,Shape类中成员函数getarea()、getperim()、getVertexCount()都声明为纯虚函数之后,基类中可以不再给出函数的实现部分,而纯虚函数的函数体由派生类给出。且Circle、Rectangle、Square类的这三个成员函数都声明为虚函数,让基类Shape类的指针sp可以调用new对象对应的、需要的功能函数,这时,派生类的虚函数会覆盖基类的虚函数,发生了动态绑定,实现多态效应。
  • 此外,需要注意的是,Square类的几个成员函数都有访问到父类的数据pl,pw,因私有private成员只能被本类成员(类内)和友元访问,不能被派生类访问,而保护protected成员可以被派生类访问,故将pl,pw声明定义为保护成员,以供派生类Square类的成员函数使用。

总结 :

此习题章内容涉及到指针的多态效应(静态绑定、动态绑定)以及还有运算符重载等内容,可以参考以下网址进行学习理解:C++多态性实例讲解 - C++教程 - C语言网C++多态性实例讲解多态性多态性是面向对象程序设计的重要特性之一,从字面意思上可以简单理解就是:多种形态,多个样子。其实本质意思也是这样,在面向对象程序设计中,指同样的方法被不同对象执行时会有不同的执行效果。具体来说,多……https://www.dotcpp.com/course/79

本专栏为本人大二C++课程的习题作业和一些学习经验的分享,供大家参考学习。如有侵权请立即与我联系,我将及时处理。


参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉,董渊、C++语言程序设计 第五版 -清华大学出版社- 郑莉,董渊(学生用书)

编译环境:Visual Studio 2019、Dev-C++

C++语言程序设计第五版 - 郑莉(第八章课后习题)相关推荐

  1. 第三章 函数 C++语言程序设计第五版 - 郑莉

    本专栏为C++学习笔记,参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉 B站视频:https://space.bilibili.com/702528832/video PPT与代码已 ...

  2. C++语言程序设计第五版 - 郑莉-绪论(一)

    本专栏为C++学习笔记,参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉 B站视频:https://space.bilibili.com/702528832/video PPT与代码已 ...

  3. C++语言程序设计第五版 - 郑莉(第六章课后习题)

    第6章   数组.指针与字符串 6-20 实现一个名为 SimpleCircle 的简单圆类.其数据成员 int* itsRadius 为一个指向其半径值的指针,存放其半径值.设计对数据成员的各种操作 ...

  4. C++语言程序设计第五版 - 郑莉(第四章课后习题)

    第4章  类与对象 4-9设计并测试一个名为rectangle的矩形类,其属性为矩形的左下角与右上角坐标,根据坐标能计算矩形的面积. #include <iostream> using n ...

  5. C++语言程序设计第五版 - 郑莉(第七章课后习题)

    第7章  继承与派生 7-5 定义一个基类 Shape,在此基础上派生出 Rectangle 和 Circle,二者都有 getArea()函数计算对象的面积.使用 Rectangle类创建一个派生类 ...

  6. C++语言程序设计第五版 - 郑莉(第五章课后习题)

    第5章  数据的共享与保护 5-7定义一个Cat类,拥有静态数据成员 numOfCats,记录Cat的个体数目:静态成员函数getNumOfCats(),读取numOfCats.设计程序测试这个类,体 ...

  7. C++语言程序设计第五版 - 郑莉(第九章课后习题)

    第9章  群体类和群体数据的组织 9-1 编写程序提示用户输入一个班级中的学生人数 n,再依次提示用户输入 n 个人在课程 A 中的考试成绩,然后计算出平均成绩,显示出来.请使用本书第 9 章中的数组 ...

  8. C++语言程序设计第五版 - 郑莉(第二章课后习题)

    第2章  C++简单程序设计 2-25 编写一个完整的程序,实现功能:向用户提问"现在正在下雨吗?",提示用户输入Y 或N.若输入为Y,显示"现在正在下雨.": ...

  9. C++语言程序设计第五版 - 郑莉(第十一章课后习题)

    第11章  流类库与输入输出 11-3 使用 I/O 流以文本方式建立一个文件 test1.txt,写入字符"已成功写入文件!",用其他字处理程序(例如 Windows 的记事本程 ...

  10. C++语言程序设计第五版 - 郑莉(第三章课后习题)

    第3章  函数 3-8 编写函数把华氏温度转换为摄氏温度,公式为:C = (F - 32) * 5/9 在主程序中提示用户输入一个华氏温度,转化后输出相应的摄氏温度. #include<iost ...

最新文章

  1. CentOS上安装skype
  2. NASA告诉你四翼飞行器的飞行原理
  3. Visual Studio 窗口的图标、图片资源 $this.Icon 在哪查看
  4. vscode配置js环境_VS Code配置Python开发环境
  5. MySQL03:DML语言
  6. KVM详解(三)——KVM创建虚拟机
  7. oh my Zsh使用手册
  8. 分布式系统的发展历程
  9. r语言平均值显著性检验_5.3 两总体均值检验和方差分析的R语言操作(26页)-原创力文档...
  10. 【服务器数据恢复】IBM DS系列存储硬盘故障导致RAID5崩溃的数据恢复
  11. 知晓云 php,2020 知晓云小程序年度评选获奖名单发布
  12. 第一次课 优秀作业展示
  13. 字节跳动以 50 亿元收购 Pico 入局 VR;哪吒汽车与华为达成合作;韩国计划禁止苹果和谷歌向开发者抽取佣金 | EA周报...
  14. 求一元多项式pn(x)=a(i)x^i(i~n的和)的值pn(x0),并确定算法中每一语句的执行次数和整个算法的时间复杂度。注意选择你认为较好的输入和输出方法。本题的输入为a(i)(i=0,1,.
  15. 入门经典_Chap08_题解总结:极角扫描法 滑动窗口 单调队列 单调栈
  16. tensorflow报InvalidArgumentError (see above for traceback): Conv2DSlowBackpropInput
  17. 助理电子商务师html,助理电子商务师考试HTML相关试题汇总.doc
  18. 浙江大学软件学院三维动画与交互技术考试概念整理
  19. 实例六 自动售饮料机
  20. 暑期实习|转行|宝洁供应链训练营面经

热门文章

  1. 独立的物联网卡管理平台有什么用?
  2. 线性表中有n个元素,每个元素是一个字符,现存于向量R[n]中,试写一算法,使R中字符按字母字符、数字字符和其他字符的顺序排列。要求利用原来的存储空间,元素移动次数最小。
  3. html5制作一个立方体,CSS3 3D transforms系列教程-立方体
  4. 嵌入式编程上下文切换的一种方案
  5. python培训大计教育先进
  6. 智库说 | 杨军:ET城市大脑为城市装上数据“操作系统”
  7. 几个免费的国外php空间
  8. 利用arcpy进行modis数据转化(hdf批量转化为tiff)
  9. Python代码实战(初级篇)————7、斐波那契数列
  10. AS中日志工具Logcat的设置及使用