C++面向对象程序设计的一些知识点(3)
摘要:多态性提供一组统一的调用接口函数,依据这些条用接口函数具体对象的不同,同一名字的函数会有不同的行为。
1、重载与隐藏
(1)、对同一作用域中的同名函数,如果它们的函数特征标不同,那么它们就形成一种重载关系。
(2)、基类与派生类中非虚同名函数,不管它们的参数特征标是否相同,它们都形成隐藏关系,即派生类对象隐藏基类中的同名函数。
#include <iostream> using namespace std; class Animal
{
public:
void walk()
{
cout << "Animal walk.\n";
}
void walk(int walkWay)
{
switch(walkWay)
{
case :
cout << "Animal jump...\n";
break;
case :
cout << "Animal fly...\n";
break;
default:
cout << "Animal scrawling...\n";
}
}
void sleep()
{
cout << "Animal sleeping..." << endl;
}
};
class Human:public Animal
{
public:
void sleep()
{
cout << "Human sleep, lying...\n";
}
}; int main()
{
Animal *pAnimal = NULL;
Animal animal;
Human human; pAnimal = &animal;
pAnimal->sleep(); pAnimal = &human;
pAnimal->sleep(); Human *pHuman = &human;
pHuman->sleep(); pHuman->walk();
pHuman->walk(); int c;
cin >> c;
return ;
}
(3)、在此示例代码中,同一类中的成员函数walk()与walk(int walkWay)形成重载。
(4)、分别位于基类Animal与派生类Human中的成员函数sleep()形成隐藏关系,即派生类Human的sleep()隐藏了基类的Animal中成员函数sleep()。
(5)、依据基类和派生类的兼容性原则,可以将派生类Human对象human的地址赋值给基类Animal的指针pAnimal。不过这时pAnimal指向的函数永远是基类的成员函数。
(6)、由于派生类Human的sleep()隐藏了基类Animal中的成员函数sleep(),所以pHuman->sleep()调用派生类Human的sleep()。
(7)、注意:基类指针永远无法调用该基类派生的同名函数。
2、多态性
(1)、虚函数:若类的成员函数用关键字virtual修饰,则称该函数为该类的虚函数,其声明语法如下:
virtual 返回值类型 函数名(形参列表);
例如:
class Animal
{
public:
virtual void sleep()
{
cout << "Animal sleep." << endl;
}
};
(2)、函数覆盖:若位于基类和派生类中的两个同名虚函数的声明完全相同(包括返回值类型),则这样的两个函数形成覆盖关系。
例如:
class Pet
{
virtual void sleep()
{
cout << "Pet sleep." << endl;
}
};
class Fish:public Pet
{
virtual viod sleep()
{
cout << "Fish sleep." << endl;
}
};
(3)、多态性实现步骤:
1)、在基类中说明成员函数为virtual函数,在直接派生类或间接派生类中根据实际应用重写这些virtual函数。
2)、在直接派生类或间接派生类中覆盖那些virtual函数,它们的声明必须和基类对应的虚函数声明严格一致。
3)、声明基类指针或者基类引用;给基类指针或者引用赋值,此时对象地址既可以是基类对象地址,也可以是派生类对象地址;有指针或者引用去调用相应的virtual函数,
根据对象的不同,真正被调用的函数可以是基类同名函数,也可以是派生类同名函数。
#include <iostream> using namespace std; class Animal
{
public:
virtual void walk()
{
cout << "Animal walk." << endl;
}
void walk(int walkWay)
{
switch(walkWay)
{
case :
cout << "Animal jump..." << endl;
break;
case :
cout << "Animal fly..." << endl;
break;
default:
cout << "Animal scraling..." << endl;
}
}
virtual void sleep()
{
cout << "Animal sleeping..." << endl;
}
private:
}; class Human:public Animal
{
public:
virtual void walk()
{
cout << "Human walk by feet." << endl;
}
virtual void sleep()
{
cout << "Human sleep, lying..." << endl;
}
virtual void talk()
{
cout << "Human talking..." << endl;
}
private:
};
int main()
{
Animal *pAnimalArray[] = {
new Animal, new Human
};
for(int i = ;i < ;i++)
{
pAnimalArray[i]->walk();
pAnimalArray[i]->sleep();
delete pAnimalArray[i];
}
int c;
cin >> c;
return ;
}
(4)、注意:若在类中只声明虚函数原型,则在类外部定义虚函数时不必加virtual关键字;若派生类覆盖基类某个虚函数,则派生类中对应的虚函数可以加virtual也可以
加;一个虚函数,他在直接派生类和间接派生类中依然保持虚函数的特性;虚函数必须是成员函数;只有通过指针或引用方式访问虚函数,才能获得虚函数的动态特性。
3、virtual析构函数
(1)、通常,我们会才用基类指针或引用来指向派生类对象,此时,使用delete释放堆中的对象时,只会释放其基类子对象部分而不会自动释放派生类子对象部分。解决
办法是把基类和派生类的析构函数都声明为virtual类型。
#include <iostream> using namespace std; class Vehicle
{
public:
Vehicle(int power)
{
this->power = power;
}
virtual ~Vehicle()
{
cout << "deleting Vehicle sub object..." << endl;
}
public:
virtual void run()
{
cout << "Vehicle running..." << endl;
}
private:
int power;
};
class Plane:public Vehicle
{
public:
Plane(int power, double height):Vehicle(power)
{
this->height = height;
}
virtual ~Plane()
{
cout << "deleting Plane sub object..." << endl;
}
public:
void run()
{
cout << "Plane fly..." << endl;
}
private:
double height;
};
int main()
{
{
Vehicle *pVehicle = new Plane(, );
delete pVehicle;
}
int c;
cin >> c;
return ;
}
4、纯虚函数和抽象类
(1)、纯虚函数:类中的virtual成员函数,如果没有实现体(即定义实现体为0),则称这样的函数为纯虚函数。
例如:
virtual void add()=0;
(2)、抽象类:当一个类含有一个或者多个纯虚函数时,称这样的类为抽象类。
注意:抽象类的纯虚函数可以是我们后续加入的或者从基类继承的,当然如果一个类继承一个或多个纯虚函数之后再一一实现这些纯虚函数,那么这样的类不再是抽象类;
抽象类不能用于创建对象,但允许定义抽象对象指针。
#include <iostream> using namespace std; const double PI = 3.14159; class Shape
{
public:
virtual void show() = ;
virtual double area() = ;
virtual ~Shape()
{}
};
class Shape2D:public Shape
{
public:
Shape2D(double x, double y)
{
this->x = x;
this->y = y;
}
protected:
double x;
double y;
};
class Shape3D:public Shape
{
public: protected:
double x;
double y;
double z;
};
class Circle:public Shape2D
{
public:
Circle(double x, double y, double radius):Shape2D(x, y)
{
this->radius = radius;
}
virtual void show()
{
cout << "Circle center: (" << x << ", " << y << ")" << endl;
}
virtual double area()
{
return PI*radius*radius;
}
private:
double radius;
};
class Sphere:public Shape3D
{
public:
Sphere(double x, double y, double z, double radius)
{
this->x = x;
this->y = y;
this->z = z;
this->radius = radius;
}
void show()
{
cout << "Sphere center:(" << x << ", " << y << ", " << z << ")" << endl;
}
double area()
{
return PI*radius*radius*radius;
}
private:
double radius;
};
int main()
{
{
Shape *pShape = NULL;
Shape *pShapeArray[] = {
new Circle(1.0, 2.0, 3.0),
new Sphere(1.0, 2.0, 3.0, 4.0)
};
for(int i = ;i < ;i++)
{
pShapeArray[i]->show();
cout << "\t area = " << pShapeArray[i]->area() << endl;
delete pShapeArray[i];
}
}
int c;
cin >> c;
return ;
}
C++面向对象程序设计的一些知识点(3)的更多相关文章
- C++面向对象程序设计的一些知识点(5)
摘要:运算符能给程序员提供一种书写数学公式的感觉,本质上运算符也是一种函数,因此有类内部运算符和全局运算符之分,通过重载,运算符的“动作”更加有针对性,编写代码更像写英文文章. 1.C++标准允许将运 ...
- C++面向对象程序设计的一些知识点(4)
摘要:累继承可以实现源代码重用,模板技术也可以达到同样的目的.模板可以分为函数模板和类模板,其共同点是允许参数类进行类型化,编译器根据程序员传递的具体类型,又把函数模板实例化为具体函数,把类模板实例化 ...
- C++面向对象程序设计的一些知识点(2)
1.C++中三种继承方式及派生类中访问控制规则 (1).C++支持的三种继承方式是public.protected.private.C++允许一个类同时以不同的方式对不同的基类加以继承. (2). 不 ...
- C++面向对象程序设计的一些知识点(1)
1.函数重载而不出错是有条件的: (1).这些函数位于同一域内,如同一类中.同一文件中. (2).这些同名函数具有不同的参数特征标(特征标是指形參的个数.类型.排列顺序等). 2.引用特性(与指针对比 ...
- 对面向对象程序设计(OOP)的认识
前言 本文主要介绍面向对象(OO)程序设计,以维基百科的解释: 面向对象程序设计(英语:Object-oriented programming,缩写:OOP),指一种程序设计范型,同时也是一种程序开发 ...
- 20162317袁逸灏 第八周实验报告:实验二 Java面向对象程序设计
20162317袁逸灏 第八周实验报告:实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 ...
- 2018-2019-2 20175217 实验二《Java面向对象程序设计》实验报告
一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:吴一凡 学号:20175217 指导教师:娄嘉鹏 实验日期:2019年4月15日 实验时间:--- 实验序号:实验二 实验名称:Jav ...
- 20175315 实验二《Java面向对象程序设计》实验报告
20175315 实验二<Java面向对象程序设计>实验报告 一.实验内容及步骤 1.初步掌握单元测试和TDD 单元测试 任务一:三种代码 用程序解决问题时,要学会写以下三种代码: 伪代码 ...
- 2018-2019-2 20175202实验二《Java面向对象程序设计》实验报告
2018-2019-2 20175202实验二<Java面向对象程序设计>实验报告 一.实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初 ...
随机推荐
- vue 虚拟dom
https://segmentfault.com/a/1190000008291645 一个VNode的实例对象包含了以下属性 tag: 当前节点的标签名 data: 当前节点的数据对象 VNode可 ...
- 生产服务器环境最小化安装后 Centos 6.5优化配置备忘
生产服务器环境最小化安装后 Centos 6.5优化配置备忘 作者:Memory 发布于:2014-8-13 15:00 Wednesday 服务器 本文 centos 6.5 优化 的项有18处: ...
- springmvc+spring框架
jar包 com.springsource.javax.validation-1.0.0.GA.jar com.springsource.org.aopalliance-1.0.0.jar com.s ...
- 苹果越狱后必备软件,总有你需要的!11月23日追加14个,支持【iOS4】
http://bbs.dospy.com/thread-7398730-1-301-2.html越狱后必备软件,总有你需要的!11月23日追加14个,支持[iOS4] 背景自定义插件
- 解决 无法将文件" "复制到“bin\*.*”。对路径“bin\*.*”的访问被拒绝。
关于这个问题今天碰到了, 我的解决办法很简单: 删除bin目录下的所有文件,然后重新生成,就不报错了.
- Java生成唯一GUID
GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制值. GUID ...
- oc 类的使用
//定议一个Hello类,用@interface @end包着,并且继承NSObject @interface Hello : NSObject{ int num; }//包在大括号里面是私有的属性, ...
- pylot 学习笔记
安装步骤 1.下载pylot 版本是1.26,文件名是:pylot_1.26.zip 2.下载python 版本是2.5,文件名是:python-2.5.msi 3.下载numpy 版本是1.4.1, ...
- Accounting_会计基础
会计基础 1.会计:是以货币为主要计量单位,反映和监督一个单位经济活动的一种经济管理工作. 2.会计核算职能:指以货币为主要计量单位,通过确认.记录.计算.报告等环节,对特定主体的经济活动进行记账.算 ...
- OGG_GoldenGate数据控制进程Manager(案例)
2014-03-03 Created By BaoXinjian