C++ 多态

多态

多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。

C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。

下面的实例中,基类 Shape 被派生为两个类,如下所示:

#include <iostream>
using namespace std; class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0){
width = a;
height = b;
}
int area(){
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) {}
int area (){
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) {}
int area (){
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5); int a = rec.area();
cout<<a<<endl;
int b = tri.area();
cout<<b<<endl;
return 0;
}

以上代码,就是Shape被派生为Rectangle 和 Triangle 两个类,正显示了C++的多态性。

其运行输出结果为:

Rectangle class area :
70
Triangle class area :
25

虚函数

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定

纯虚函数

您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。

我们可以把基类中的虚函数 area() 改写如下:

class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};

= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数

注意

  1. 派生类中一般需要重定义所继承的虚函数,若没有则使用基类版本
  2. 一旦函数被声明为虚函数,则派生中一直为虚函数;派生类中可以使用关键字virtual,也可以不保留
  3. 虚函数重定义时候,原型不能变:返回类型、形参数目和类型都不能更改;若不一致则为重载
  4. 构造(三大类)函数不能做为虚函数,静态成员函数不能定义为虚函数

    在构造函数运行的时候,这个对象的动态类型还不完整,没有办法确定它到底是什么类型,故构造函数不能动态绑定

    静态的数据成员被所有的对象共享,静态数据成员不属于对象,而是属于类的;静态成员函数也是属于类的,它没有this指针,它无法进行对象的判别
  5. 构造及析构函数体内切勿使用虚函数

    在进行基类成员构造的时候对象就被编译器视为基类类型;派生类部分的成员还没有初始化,想调用派生类的虚函数相当于要去使用未定义的数据;另外,若此时涉及到调用虚函数,也是基类的虚函数,是不可能正确实现多态的

    析构函数同理
  6. 虚析构函数

    虚析构函数是根据对象的类型来动态释放基类/派生类的对象的

    意味着可以用基类的引用释放派生类的对象的空间

    当基类中有虚函数时,最好将析构函数也声明为虚函数
  7. 虚函数的屏蔽

    作用域符号 : : 可以强制调用指定的虚函数,因为派生类的对象可以赋值给基类,传入派生类对象依然可以执行基类定义的虚函数
  8. 纯虚函数 纯虚函数是用来被继承的;纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务

最新文章

  1. linux常用命令-文件搜索命令-find
  2. [canvas]利用canvas绘制自适应的折线图
  3. Codeforces Round #364 (Div. 2) B. Cells Not Under Attack
  4. temp--test audio micphone
  5. [QTP/UFT12]无限延长试用期的方法
  6. c++11 内存模型解读
  7. Partitioner
  8. D2 前端技术论坛总结(下)
  9. android 自定义progressDialog实现
  10. 菜鸟学习Ado.net笔记一:Ado.net学习之SqlHelper类
  11. hdu 5423 Rikka with Tree(dfs)
  12. jquery判断对象的type
  13. 由于IPv6导致的iOS应用发布失败,是否该怪Azure?
  14. numastat的理解
  15. 使用 Rust 构建分布式 Key-Value Store
  16. FM与PM信号的表现形式
  17. LeetCode——295. Find Median from Data Stream
  18. 【Android】解析Paint类中MaskFilter的使用
  19. Golang的值类型和引用类型的范围、存储区域、区别
  20. time_base

热门文章

  1. iOS之CAScrollLayer属性简介和使用
  2. Spring MVC(五)--控制器通过注解@RequestParam接受参数
  3. java浮点运算的陷阱
  4. Compile_Netgen_WITH_OpenCascade
  5. java后台对上传的图片进行压缩
  6. HBase 物理视图
  7. Android开发 Camera2开发_2_预览分辨率或拍照分辨率的计算
  8. innodb状态
  9. vue.js_08_vue-组件的定义
  10. php条件语句(一)