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.析构函数 当一个对象被创建时,自动调用构造函数进行初始化 当一个对象被销毁时,自动调用析 ...
随机推荐
- ios 常用宏(copy)
分享一下我现在用的 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 3 ...
- javaScript滚动新闻之上下左右平滑滚动
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- php 实现二进制加法运算
php实现二进制加法: 思路:没有工作中应用过此场景,但十进制的加法还是经常做的,能不能用十进制加法变相实现呢? 答案是可以的,并且php也提供进制间转换的函数,我的实现使用了 bindec():二进 ...
- SQL函数介绍
http://www.cnblogs.com/moss_tan_jun/archive/2010/08/23/1806861.html 一旦成功地从表中检索出数据,就需要进一步操纵这些数据,以获得有用 ...
- 更改Oracle数据文件名及数据文件存放路径
更改Oracle数据文件名及数据文件存放路径 SQL> select * from v$dbfile; FILE# NAME ---------- ---------------- ...
- BZOJ 3672: [Noi2014]购票( 树链剖分 + 线段树 + 凸包 )
s弄成前缀和(到根), dp(i) = min(dp(j) + (s(i)-s(j))*p(i)+q(i)). 链的情况大家都会做...就是用栈维护个下凸包, 插入时暴力弹栈, 查询时就在凸包上二分/ ...
- redis memcache
谈谈Memcached与Redis(一) 1. Memcached简介 Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高 ...
- http keepalive and tcpkeepalive
http keepalive 减少tcp 连接 (三次握手的消耗) tcp keepalive 检测死链接的 session 在tcp连接中, src_ip + src_port + dest_ip ...
- JavaWeb核心编程之使用Eclipse开发JavaWEB项目
文章目录 1.eclipse切换到javaee项目 2.创建服务器(如果没有server选项, 怎么做) 3.定制新建面板内容 4.创建动态web工程 1.eclipse切换到javaee项目 如图 ...
- B/S结构和C/S结构
概念: C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境 ...