C++_基础_继承、多态
内容:
(1)子类中的拷贝构造和拷贝赋值
(2)多继承和虚继承
(3)多态的初识
(4)虚析构的特性和使用
(5)多态的底层实现
(6)纯虚函数、抽象类的概念
1.子类中的拷贝构造和拷贝赋值
子类中的拷贝构造和拷贝赋值可能也需要显式的指定父类子对象的拷贝构造和拷贝赋值的方式
2.多继承和虚继承
2.1 格式:
class 子类名 : 继承方式 父类名1,继承方式 父类名2,...
{
//子类中的属性和行为
};
如:
员工类
/ \
销售员工类 管理者类
\ /
销售管理类
叫做:钻石继承
2.2 虚继承要点
(1)在对公共基类的继承方式之前加virtual关键字修饰
(2)可能需要在最终子类中显式指定公共基类的构造方式
(3)目标:公共基类子对象在最终子类中只有一份,以避免从不同继承路径访问公共基类子对象时发生数据不一致的现象
注意:
在多继承中,如果多个父类都有函数名相同,参数表不同的函数,继承到子类中不会构成重载,如果子类中存在同名的标示符,则产生隐藏(02diamond.cpp文件)
练习:
写一个圆类(Circle),属性有:圆心坐标和半径;再写一个桌子类(Table),属性有:高度;两个类共同派生一个圆桌类(RoundTable),属性:颜色
要求:定义一个圆桌类的对象,打印出圆桌的桌面面积,体积以及颜色
圆的面积:PI*r*r;
圆的体积公式:底面积 * 高
(vi 03circle.cpp)
3.多态的初识
3.1 多态的特性
(1)通过指向子类对象的 基类指针/引用 只能调用基类中的成员函数
(2)通过指向子类对象的 基类指针/引用 调用虚函数,实际上调用的是子类中的版本
(3)虚函数和虚函数覆盖
虚函数:使用virtual关键字修饰的函数
虚函数覆盖:在子类中定义一个与基类中具有相同的函数原型的函数,即构成虚函数覆盖,该虚函数的覆盖版本也是虚函数(无论是否使用virtual修饰)
(04dynamic.cpp文件)
笔试题:
class B : public A{};
基类中:virtual A* foo(void){...}
子类中:virtual B* foo(void){...}
=> 产生虚函数覆盖
4.虚析构
使用virtual关键字修饰的析构函数
(1)虚析构函数实际上就是为了保证delete一个指向子类对象的基类指针时,实际上被调用的是子类中的析构函数,而子类中的析构函数会自动调用基类中的析构函数
(2)一般而言,如果一个类中有虚函数,那么该类就应该提供一个虚析构函数
(05destructor.cpp文件)
5.多态的底层实现
5.1 实现流程
如:
class A{...};
class B : public A{...};
A* pa = new B;
pa->foo();
当编译器编译上句代码时,它并不知道pa的所真正指向的真实对象(只有在运行时才会知道),编译器所能做的就是使用一段代码去替换上面的函数调用语句,这段代码依次执行下面的操作:
(1)首先弄清指针pa所指向的对象的真实身份
(2)然后通过这个对象的虚函数表指针去访问对应的虚函数表,并找到与foo函数标示符所对应的虚函数入口地址
(3)根据入口地址调用该函数
5.2 多态必要条件
(1)虚函数
(2)通过指针/引用 去调用
笔试题:
(1)
class A
{
public:
void foo(void)
{
// this = &b;
// this->bar();
bar();//调用B类中的bar函数
}
virtual void bar(void){...}
};
class B : public A
{
public:
//虚函数覆盖
void bar(void){...}
};
int main(void)
{
B b;
b.foo();
return 0;
}
(2)
构造函数、析构函数以及静态成员函数中,哪些函数可以是虚函数?
析构可以是虚函数
构造函数和静态成员函数不可以是虚函数
C++_基础_继承、多态的更多相关文章
- Python设计模式 - 基础 - 封装 & 继承 & 多态
面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...
- 07JAVA基础面向对象-继承/多态
一.继承 1.概念 子类的共性 重用现有类并在此基础上进行扩展 public class 子类 extends 父类{} 2.继承中的成员访问 成员变量 成员方法 局部->本类中成员变量-> ...
- C# 面向对象基础&封装&继承&多态&加深一下冒泡排序写法
(一)面向对象是什么? 面向对象是一种编程思想 (二)为什么要用面向对象? 1.结构清晰 2.易于维护 3.方便扩展 (三)new一个对象是什么过程? 实例化构造函数创建对象的过程就是将类实例化的过程 ...
- <python基础>封装,继承,多态,重写,重载
什么是封装? 所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面,这就是封装.封装是我们所说的面相对象编程的特征之一.除此之外还有继 ...
- C++_基础_运算符重载2
内容: (1)只能用成员形式重载的运算符 (2)new/delete操作符的重载 (3)封装和继承的初识 (4)继承的特性 (5)子类及其函数的特性 (6)多重继承和虚继承 1.只能用成员形式重载的运 ...
- C++_基础_类和对象
内容: (1)引用 (2)类型转换 (3)C++社区给C程序员的建议 (4)面向对象编程的概念 (5)类和对象 (6)构造函数 (7)初始化列表及其必要性 1.引用1.1 指针和引用的使用说明(1)指 ...
- java工程师_基础_阶段一_HTML笔记篇
一.了解HTML语言 html:超文本标记语言. 二.HTML整体结构<html> <head> </head> <body> </body> ...
- C++_基础_运算符重载
内容: (1)输入输出运算符重载 (2)友元类和友元函数 (3)双目运算符重载 (4)单目运算符重载 (5)不能被重载的运算符 (6)只能定义为成员形式的运算符 1.输入输出运算符重载如: int n ...
- C++_基础_类和对象3
内容: (1)析构函数 (2)拷贝构造和拷贝赋值 (3)静态成员 (4)成员指针 (5)输入输出运算符重载 1.析构函数 当一个对象被创建时,自动调用构造函数进行初始化 当一个对象被销毁时,自动调用析 ...
随机推荐
- C# NameValueCollection集合 .
案例: NameValueCollection nameValueCollection = Request.Params;//获得连接地址中的所有参数 //获取各个参数,eg: ...
- Linux--根文件系统的挂载过程分析
前言: 本篇文章以S3C6410公版的Linux BSP和U-Boot来进行分析,文中全部提及的名词和数据都是以该环境为例,全部的代码流程也是以该环境为例来进行分析.哈哈.假设有不对或者不完好的地方, ...
- 黑马程序员 Java基础<十八>---> 网路编程
--------------- ASP.Net+Android+IO开发S..Net培训.期待与您交流! --------------- 第一 概述 一.概述: 1.网络模型:OSI参考模型和TCP ...
- EF实体框架-从数据库更新模型 一部分表的外键(导航属性)无法显示
从数据库更新模型 要想让数据库表之间的外键关系 显示到实体模型的导航属性中去. 表的外键 对应另一张表的字段要是主键,唯一键显示不出来
- C#中的Attributes的用法
今天研究了一下C#中的Attributes的用法,感觉很有用,现总结以下: 在前台用JS写的脚本方法,除了可以直接用在前台控件的属性中,还可以在后台运用. 即在后台页面加载时,调用JS方法.语法格式有 ...
- Windows Server 2008 Enterprise使用12G内存
开启PAE选项,用以下命令解决这个问题: 1.开始运行cmd2.输入 BCDEdit /set PAE forceenable 后回车3.重起系统显示12GB内存,一切正常
- PagerAdapter instantiateItem()方法position错误解决方案
异常信息:java.lang.IndexOutOfBoundsException: index=3 count=2 在instantiateItem各个条目View的时候.会有 container.a ...
- sass教程
sass教程 1. 使用变量; sass让人们受益的一个重要特性就是它为css引入了变量.你可以把反复使用的css属性值 定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值.或者,对于仅使 ...
- linux的nohup命令的用法。
在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会 用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /usr/local/mysql/bin/m ...
- @RISK
Price: AUD $3,295.00 Price: AUD $2,495.00 适用于项目管理的 @RISK 免费试用版下载 » 立即购买 » 价格对比 » 许可选项 (英文) » 教学计 ...