C++笔记(10):多重继承

                        多重继承

C++允许一个派生类继承自另一个类。

同时又允许一个派生类同时继承多个基类。这被称为多重继承。
 
声明多重继承的方法
class D: public A, public B, public C
{
   //...
};
 
D是多重继承的派生类。它以公有继承的方式同时继承自A、B、C。
 
构造函数构造顺序
D:D()
 :A(), B(), C()
{
}
 调用顺序为:先调用基类的构造函数,在执行派生类的构造函数。基类的构造函数调用顺序按照声明派生类时基类的出现顺序。
析构函数调用顺序与构造顺序相反
 
同名成员函数的二义性
在单继承下,基类的public 和protected 成员可以直接被访问,就像它们是派生类的成员一样,对多继承这也是正确的。但是在多继承下,派生类可以从两个或者更多个基类中继承同名的成员。然而在这种情况下,直接访问是二义的,将导致编译时刻错误。
例如,如果A和B 都定义了一个成员函数print(),
则如下语句:
D d;
d.print();
将导致编译时错误,即使这两个通过继承得到的成员函数定义了不同的参数类型:
原因在于继承得到的成员函数没有构成派生类中的重载函数,因此,对于print()调用,编译器在解析的时候,只是使用了针对print 的名字解析。解决的方法是在方法前加上所属的类d.A::print();
 
虚基类
尽管在派生列表中不允许同一个基类出现两次,但实际上派生类可以多次继承同一个类。

派生类通常会含有继承链上每个类对应的子部分。在上面的两种情况中,class D都间接地继承了class A两次,那么意味着class D中包含了class A的两份拷贝。所以在一个class D的对象中将含有2组class A的成员,此时若不加前缀限定符直接使用某个成员将引发“二义性”错误:
为了解决上述问题,C++提供了虚继承的机制。虚继承的目的是令某个类作出声明,承诺愿意共享它的基类。共享的基类子对象称为虚基类。在这种机制下,不论虚基类在继承体系中出现多少次,在派生类中都只包含唯一一个共享的虚基类子对象。我们指定虚基类的方式是在派生列表中添加关键字virtual:
class B: virtual public A
{
}
 
class C: virtual public A
{
}
class D: public B,public C
{
}
 含有虚基类的对象的构造顺序与一般的多重继承的构造顺序稍有区别:先初始化虚基类子对象(最低层派生类负责),然后按派生列表中的顺序依次对直接基类(非虚)进行初始化。

时间: 2024-10-07 05:31:24

C++笔记(10):多重继承的相关文章

jQuery学习笔记10:Ajax技术

jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据. jQuery 采用了三层封装:最底层的封装方法为:$.ajax(),而通过这层封装了第二层有三种方法:.load().$.get()和$.post(),最高层是$.getScript()和$.getJSON()方法. 函数 描述 jQuery.ajax() 执行异步 HTTP (Ajax) 请求. .ajaxComplete() 当 Ajax 请求完成时注册要调用的处理程序.这是一个

Android:日常学习笔记(10)———使用LitePal操作数据库

Android:日常学习笔记(10)---使用LitePal操作数据库 引入LitePal 什么是LitePal LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式,将平时开发时最常用的一些数据库功能进行了封装,使得开发者不用编写一行SQL语句就可以完成各种建表.増删改查的操作.并且LitePal很"轻",jar包大小不到100k,而且近乎零配置,这一点和Hibernate这类的框架有很大区别.目前LitePal的源码已经托管到了GitHub上. 关

sqlite学习笔记10:C语言中使用sqlite之查询和更新数据

前面说到的 sqlite_exec() 中的第三个参数, SQLite 将为 sql 参数内执行的每个 SELECT 语句中处理的每个记录调用这个回调函数. 本节添加了两个函数,selectFromTable和updateTable. 实例程序如下: #include <stdio.h> #include <stdlib.h> #include "sqlite/sqlite3.h" #define DB_NANE "sqlite/test.db&quo

lua学习笔记10:lua简单命令行

前面多次用了命令行,这次就好好学下命令行: 一 格式 lua [options][script][args] 二 具体命令 -e 直接将命令传个lua -l 加载一个文件 -i 进入交互模式 例如,终端输入: lua -e "print(math.sin(12))" lua学习笔记10:lua简单命令行,布布扣,bubuko.com

[模式识别].(希腊)西奥多里蒂斯&lt;第四版&gt;笔记10之__监督学习:后记

本章是监督学习的最后一部分,主要有三个目标.   首先,根据系统的分类错误概率来评估系统性能. 其次,将整个系统设计的各个阶段组合到一起. 最后,引入无标签数据,简单介绍半监督学习 1,ERROR-COUNTING方法 2,探求有限的数据集的大小 3,一个医学图像的学习案例 4,半监督学习:生成模型(generative model);基于图的方法(graph-based method); Transductive Support Vector Machines [模式识别].(希腊)西奥多里蒂

python基础教程_学习笔记10:异常

异常 什么是异常 Python用异常对象来表示异常情况.遇到错误后,会引发异常.如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止执行: >>> 1/0 Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> 1/0 ZeroDivisionError: integer division or modulo by

Perl语言学习笔记 10 其他控制结构

1.unless控制结构 条件为假时执行,与if相反 可以附带else 2.Until控制结构 条件为假时执行,一直执行到条件为真: 3.条件修饰词 效果等同于: 类似的模式: 4.裸块控制结构 { body; body; .... } 有利于为临时变量圈定有效范围 5.elsif子句 6.自增.自减 同c语言 7.for 用法同c语言 8.for与foreach 在perl中,两者等价,优先选择纯正的foreach 9.5种循环块:for.foreach.while.until.裸块 last

《C++ Primer Plus》学习笔记10

<C++ Primer Plus>学习笔记10 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<&

学习笔记10

今天来粗略的学习一下js<script></script> JavaScript:写入 HTML 输出     document.write("<h1>This is a heading</h1>"); JavaScript:对事件作出反应       <button type="button" onclick="alert('Welcome!')">点击这里</button>

thinkphp学习笔记10—看不懂的路由规则

路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INFO,PATH_INFO是什么呢?手册中提到“要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),” , url支持path_info,不是apache要支持path_info么,度娘讲的还算清楚一点,见下文: pathinfo(PHP 4 >= 4.0.3, PHP 5)path