文章目录

  • 1 C++中多态的概念和意义
    • 1.1 函数重写回顾
    • 1.2 多态的概念
    • 1.3 多态的意义
    • 1.4 静态联编和动态联编
  • 2 特殊的虚函数
    • 2.1 构造函数能成为虚函数吗
    • 2.2 析构函数能成为虚函数吗
  • 3 构造函数和析构函数中的多态

1 C++中多态的概念和意义

1.1 函数重写回顾

对于函数重写:

  • 父类被重写的函数依然会继承给子类。
  • 子类中重写的函数将覆盖父类中的函数。
  • 通过作用域分辨符(::)可以访问到父类中的函数。

1.2 多态的概念

面向对象中期望的行为:

  • 根据实际的对象类型判断如何调用重写函数。
  • 父类指针(引用)指向:
    • 父类对象则调用父类中定义的函数。
    • 子类对象则调用子类中定义的重写函数。

面向对象中多态的概念:

  • 过呢据实际的对象类型决定函数调用的具体目标。
  • 同样的调用语句在实际运行时有多种不同的表现形态。

C++语言直接支持多态的概念:

  • 通过virtua关键字对多态进行支持。
  • 被virtual声明的函数被重写后具有多态特性。
  • 被virtual声明的函数叫做虚函数。

多态示例:

#include <iostream>
#include <string>using namespace std;class Parent
{public:virtual void print(){cout << "I'm Parent." << endl;}
};class Child : public Parent
{public:void print(){cout << "I'm Child." << endl;}
};void how_to_print(Parent* p)
{p->print();     // 展现多态的行为
}int main()
{Parent p;Child c;how_to_print(&p);    // Expected to print: I'm Parent.how_to_print(&c);    // Expected to print: I'm Child.return 0;
}

1.3 多态的意义

多态的意义:

  • 在程序运行过程中展现出动态的特性。
  • 函数重写必须多态实现,否则没有意义。
  • 多态是面向对象组件化程序设计的基础特性。

1.4 静态联编和动态联编

静态联编:

  • 在程序的编译期间就能确定具体的函数调用,如:函数重载。

动态联编:

  • 在程序实际运行后才能确定具体的函数调用,如:函数重写。

动态联编与静态联编:

#include <iostream>
#include <string>using namespace std;class Parent
{public:virtual void func(){cout << "void func()" << endl;}virtual void func(int i){cout << "void func(int i) : " << i << endl;}virtual void func(int i, int j){cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;}
};class Child : public Parent
{public:void func(int i, int j){cout << "void func(int i, int j) : " << i + j << endl;}void func(int i, int j, int k){cout << "void func(int i, int j, int k) : " << i + j + k << endl;}
};void run(Parent* p)
{p->func(1, 2);     // 展现多态的特性// 动态联编
}int main()
{Parent p;p.func();         // 静态联编p.func(1);        // 静态联编p.func(1, 2);     // 静态联编cout << endl;Child c;c.func(1, 2);     // 静态联编cout << endl;run(&p);run(&c);return 0;
}

2 特殊的虚函数

2.1 构造函数能成为虚函数吗

构造函数不可能成为虚函数:

  • 在构造函数结束后,虚函数表指针才会被正确的初始化。

2.2 析构函数能成为虚函数吗

析构函数可以成为虚函数:

  • 建议在设计类时将析构函数声明为虚函数(发生赋值兼容时,可以正确的调用析构函数,防止内存泄漏的发生)。
#include <iostream>
#include <string>using namespace std;class Base
{public:Base(){cout << "Base()" << endl;func();}virtual void func() {cout << "Base::func()" << endl;}virtual ~Base(){func();cout << "~Base()" << endl;}
};class Derived : public Base
{public:Derived(){cout << "Derived()" << endl;func();}virtual void func(){cout << "Derived::func()" << endl;}~Derived(){func();cout << "~Derived()" << endl;}
};int main()
{Base* p = new Derived();// ...delete p;return 0;
}

输出结果:


3 构造函数和析构函数中的多态

析构函数中是否可以发生多态?
析构函数中是否可以发生多态?

构造函数中不可能发生多态行为:

  • 在构造函数执行时,虚函数表指针未被正确初始化。

析构函数中不可能发生多态行为:

  • 在析构函数执行时,虚函数表指针已经被销毁。

构造函数和析构函数中不能发生多态行为,只能调用当前类中定义的函数版本!

示例程序见2.2中的示例程序。


参考资料:

  1. C++深度解析教程

C++中多态的概念和意义相关推荐

  1. 【C++深度剖析教程27】多态的概念与意义

    今天来学习一个新的概念,多态!!!多态在C++编程中具有重要的地位与意义,是面向对象的一个重要思想! 加qq1126137994一起学习更多技术~ 1.问题引入 父类与子类之间具有赋值兼容性; *子类 ...

  2. Java 中多态的概念以及前提条件

    多态的概念  * 一个事物在不同时刻的体现(堆内存中对象形式)  * 多态的前提条件:  * 1)必须有继承关系(继承的好处第三点作为多态的前提条件)  *     如果没有继承谈不上多态  * 2) ...

  3. java中的多态的概念_java中多态的概念

    多态的概念 多态==晚绑定. 不要把函数重载理解为多态. 因为多态是一种运行期的行为,不是编译期的行为. 多态:父类型的引用可以指向子类型的对象. 比如 Parent p = new Child(); ...

  4. python多态的概念_python中的多态

    多态性是允许将父对象设置成为和一个或多个它的子对象相等的技术,比如Parent:=Child: 多态性使得能够利用同一类(基类)类型的指针来引用不同类的对象,以及根据所引用对象的不同,以不同的方式执行 ...

  5. java多态的概念_java中多态是什么?概念详解

    对于java中的多态你是怎样理解的呢?很多人表示,自己对于多态的概念不是很清楚,那么下面就让我们一起来详细的了解一下吧. 1.什么是多态? 多态简单的来说就是一种事物的多种存在形态. 在面向对象语言当 ...

  6. 深入Java核心 Java中多态的实现机制(1)

    在疯狂java中,多态是这样解释的: 多态:相同类型的变量,调用同一个方法时,呈现出多中不同的行为特征, 这就是多态. 加上下面的解释:(多态四小类:强制的,重载的,参数的和包含的) 同时, 还用人这 ...

  7. Java:多态的概念和案例实现

    一.多态的概念 多态性是指同一个操作作用于某一类对象,可有不同的解释,产生不同的执行结果 多态存在的三个必要条件         需要存在继承或实现关系         同样的方法调用而执行不同的操作 ...

  8. Java中多态的使用

    1.面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 2.多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息 ...

  9. Haskell与Python中的一些概念,若有所悟

    转自:http://blog.csdn.net/tangboyun/archive/2010/04/03/5447688.aspx 首先,必须声明的是,下面所写的内容,只是我个人的一些体验和感悟,受限 ...

最新文章

  1. 33张图剖析ReentrantReadWriteLock源码
  2. 数据挖掘基础知识-矩阵(分解)
  3. Matlab实用程序--图形应用-三维曲线图
  4. Jenkins分层作业和作业状态汇总
  5. XP系统中没有Internet信息服务windows组件解决办法
  6. 如何通过http协议知道是从那个站点过来的请求_聊聊HTTP的那些事,以及在它背后的“勾当”...
  7. Linux简单调用so库及Makefile用法
  8. 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型
  9. 折线图x轴的日期会超出_折线图技巧丨阈限颜色设置
  10. 简单的达梦数据库使用DISTINCT去重
  11. php公众号后台,微信公众号后台管理系统
  12. Linux下zip命令-不打包目标文件目录
  13. Blender学习笔记:齿轮模型建立
  14. msn 邮箱服务器,MSN邮箱的POP怎么设置?
  15. unbuntu安装docker
  16. 电子钱包电子存折,区别
  17. 考研计算机专业课408,【21计算机考研】专业课统考408院校汇总
  18. taobao.trade.fullinfo.get( 获取单笔交易的详细信息 )、淘宝店铺卖出订单详情接口,店铺订单明文接口,店铺订单解密接口,店铺订单消息推送接口
  19. 万豪国际集团在山东日照设立首家酒店
  20. “坝上”到底在哪里?

热门文章

  1. 【Matlab 图像】HSV 空间图片分离器
  2. 2.12 向量化更多例子-深度学习-Stanford吴恩达教授
  3. 9.5 程序示例--推荐系统-机器学习笔记-斯坦福吴恩达教授
  4. [python]开发IC utility 一些常用的方法和函数和语法规则
  5. 【体验】ESP32-CAM可能是最便宜的“监控”方案,ESP32-CAM程序下载调试
  6. 基于MATLAB的MIMO系统分层空时码的仿真
  7. LinkedList模拟队列和堆栈
  8. 不要使用字符串常量作为对象锁去同步代码
  9. JSP标签JSTL(4)--URL
  10. [转]javascript中style.left和offsetLeft的使用