C++多重继承与虚基类及与.NET的比较


多重继承
前面我们介绍的派生类只有一个基类,称为单基派生或单一继承。在实际运用中,我们经常需要派生类同时具有多个基类,这种方法称为多基派生或多重继承。
2.1 多重继承的声明:
在 C++ 中,声明具有两个以上基类的派生类与声明单基派生类的形式类似,只需将要继承的多个基类用逗号分开即可。
在多重继承中,公有派生和私有派生对于基类成员在派生类的可访问性与单继承的规则相同。
另外,对基类成员的访问必须是无二义的,若两个基类中具有同名的数据成员或成员函数,使用成员名限定来消除二义性,若派生类中新增成员或成员函数与基类成员或成员函数同名,则派生类会覆盖外层同名成员,也须使用作用域分辨符。
2.2 多重继承的构造函数和析构函数:
多重继承的构造函数的定义形式与单继承构造函数的定义形式类似,只有 n 个基类的构造函数之间用“,”分隔。
多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同,也是遵循先执行基类的构造函数,再执行对象成员的构造函数,最后执行派生类构造函数的原则。在多个基类之间,则严格按照派生类声明是从左到右的顺序来排列先后。而析构函数的执行顺序与构造函数的执行顺序相反。
2.3 虚基类 :
如果某个派生类的部分或全部直接基类是从另一个共同的基类派生而来,在这些基类中,从上一级基类继承来的成员就有相同的名称,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性,此时,可定义虚基类。这就要求在其直接基类的定义中,使用关键字 virtual 将那个共同的基类定义为虚基类,其语法形式如下:
class 派生类名: virtual 派生方式 基类
虚基类的初始化与一般的多重继承的初始化在语法上是一样的 ,但构造函数的调用顺序不同,虚基类构造函数的调用顺序是这样规定的:
1) 在同一层次中,先调用虚基类的构造函数,接下来依次是非虚基类的构造函数,对象成员的构造函数,派生类的构造函数。
2) 若同一层次中包含多个虚基类,这些虚基类的构造函数按对他们说明的先后次序调用
3) 若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类构造函数。

 

上面是理论,有点儿晦涩,下面举一个例子.以下图为例:

绘图1

接口Common是所有类的公共接口,Server接口继承Common接口,Client接口继承Common接口,CommonImpl是Common接口的一个公共实现。ServerImpl是Server接口的实现,它的Common接口的实现直接使用CommonImpl类的实现。

如果在C#中,这个问题会自然而优雅的解决,即编译器会知道,如果1个类继承了Server接口,又继承了CommonImpl实现,那么ServerImpl只需要实现Server接口中特定的方法即可。唯一的限制是CommonImpl必须放在Server接口的前面。看下面的演示代码:

using System;
using System.Collections.Generic;
using System.Text;namespace Demo
{interface IA{string funcInA();}interface IB : IA{string funcInB();}public class CA : IA{#region IA 成员public string funcInA(){return "CA.funcInA";}#endregion}public class CB : CA, IB{#region IB 成员public string funcInB(){return "CB.funcInB";}#endregion}}

类CB只需要实现接口IB中的方法即可。CA,IB必须以这个顺序出现;

 

对于C++而言,编译器是不知道的,如果你希望所有子类共享一个基类,或者子类都共用一个通用实现的基类,那么你需要把共享的那部分,声明为virutal基类,上图中的例子,就必须把Common的子类继承,声明为虚基类继承。

#pragma once
#include <iostream>
using namespace std;class IA
{
public:virtual int FuncInA() =0;
};class IB:virtual public IA
{
public:virtual int FuncInB()=0;
};class CA:virtual public IA
{
public:virtual int FuncInA(){cout<<" CA::FuncInA "<<endl;return 1;};
};class CB:public CA,public IB
{
public:int FuncInB(){cout<<"CB::FuncInB"<<endl;return 2;};/*virtual int FuncInA()
    {

        cout<<"CB::FuncInA"<<"  Call CA::FuncInA() ==>"<<CA::FuncInA()<<endl;
        return 3;
    };*/};

上面的代码编译可以通过,且结果如期望。如果去掉virtual继承修饰符,就会报错。

转载于:https://www.cnblogs.com/sgsoft/archive/2010/07/20/1781724.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379120.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平院实训门禁系统导入

这是我的配置&#xff08;如果是Win10最好每一步都管理员身份运行&#xff09; win7 SQLServer2008 VS2012 切记&#xff1a;注意&#xff1a;当你SQLserver创建数据库和VS连接数据库的时候得用同一种方式&#xff0c;要么都用window&#xff08;主机名&#xff09;&#xff0…

北京中信银行总行地址_中信银行拉萨分行举行“存款保险标识”启用和存款保险条例宣传活动...

11月NOV中信银行拉萨分行举行“存款保险标识”启用和《存款保险条例》宣传活动揭牌启用仪式111月Jul根据人民银行和总行关于“存款保险标识”启用工作相关要求&#xff0c;分行行领导高度重视“存款保险标识”启用和《存款保险条例》宣传活动工作&#xff0c;按照统一工作部署、…

转整型_156.Ruby烘焙大理石豆沙吐司解锁大理石花纹整型

好看又好吃的大理石豆沙面包。红豆馅均匀分布在松软细腻的面包体里&#xff0c;手撕着吃&#xff0c;一层层的甜美与温柔&#xff5e;关于吐司面包&#xff0c;我公众号里写过白吐司(基础款牛奶吐司&#xff0c;超绵鲜奶油吐司)和全麦吐司(基础款50%全麦吐司&#xff0c;经典燕…

VS2010 快捷键 (空格显示 绿点, Tab 显示箭头)

VS2010 有用的快捷键 &#xff1a; Ctrl r, ctrl w, 切换空格示。 转载于:https://www.cnblogs.com/fengye87626/archive/2012/11/21/2780716.html

分析一下mp4格式的trak -> mdia -> minf -> stbl -> stts、stsc 这两个box信息

分析一下mp4格式的trak -> mdia -> minf -> stbl -> stts、stsc 这两个box信息 &#xff08;因为这两个box在音频trak和视频trak 下都有的&#xff0c;而且都有一个数组的值是比较绕的&#xff09; 目录&#xff1a;stts&#xff1a;记录时间戳的&#xff0c;每个s…

Python---爬虫案例

例1、爬取公众号文章中的图片。 1&#xff0c;首先打开要获取公众号文章的地址 2&#xff0c;按下F12&#xff0c;再按Ctrl Shift C&#xff0c;然后鼠标移动到图片位置&#xff0c;然后观察控制台中显示图片对应的代码位置 3&#xff0c;分析该位置的代码段 代码段如下&…

Python---实验九

1、使用标准库urllib爬取“http://news.pdsu.edu.cn/info/1005/31269.htm”平顶山学院新闻网上的图片&#xff0c;要求:保存到F盘pic目录中&#xff0c;文件名称命名规则为“本人姓名” “_图片编号”&#xff0c;如姓名为张三的第一张图片命名为“张三_1.jpg”。 from re imp…

32接上拉5v_51单片机P0口上拉电阻的选择

作为I/O口输出的时候时&#xff0c;输出低电平为0 输出高电平为高组态(并非5V&#xff0c;相当于悬空状态&#xff0c;也就是说P0 口不能真正的输出高电平)。给所接的负载提供电流&#xff0c;因此必须接(一电阻连接到VCC)&#xff0c;由电源通过这个上拉电阻给负载提供电流。P…

[转载]FPGA/CPLD重要设计思想及工程应用(时序及同步设计)

来源&#xff1a;http://www.eetop.cn/blog/html/11/317611-13412.html 数字电路中,时钟是整个电路最重要、最特殊的信号。 第一, 系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错. 第二, 时钟信号通常是系统…

实验五 图形设计

每复制一个方法都要绑定Paint事件 一、创建Windows窗体应用程序&#xff0c;要求如下&#xff1a;&#xff08;源代码运行界面&#xff0c;缺少任一项为0分&#xff0c;源代码只需粘贴绘制图形代码所在的方法&#xff0c;不用粘贴太多&#xff09; 例如: &#xff08;1&…

ADO.NET与SQL Server数据库的交互

7.3.1 使用SqlConnection对象连接数据库 例如&#xff1a;建立与SQL Server数据库的连接。 string connstring"Data Sourceservername;uidusername;pwdpassword;Initial Catalogdbname";SqlConnection connnew SqlConnection(connstring);conn.Open(); 例如&#xf…

linux ftp日志_linux学习笔记(一)——Linux分区和目录结构

linux学习笔记&#xff08;一&#xff09;——Linux分区和目录结构安装Linux时&#xff0c;手动挂载分区的情况下&#xff0c;/ 和 swap 是必须要挂载的&#xff0c;其他/home、/boot 等可以根据需要自行挂载。一般来说&#xff0c;简单的话&#xff0c;建议挂载三个分区&#…

vc++ 6.0 堆栈_在C ++中使用链接列表实现堆栈

vc 6.0 堆栈To implement a stack using a linked list, basically we need to implement the push() and pop() operations of a stack using linked list. 要使用链接列表实现堆栈 &#xff0c;基本上&#xff0c;我们需要使用链接列表实现堆栈的push()和pop()操作。 Exampl…

协议地址结构_TCP/IP 协议 讲解

计算机网络体系结构分层太厉害了&#xff0c;终于有人能把TCP/IP 协议讲的明明白白了计算机网络体系结构分层不难看出&#xff0c;TCP/IP 与 OSI 在分层模块上稍有区别。OSI 参考模型注重“通信协议必要的功能是什么”&#xff0c;而 TCP/IP 则更强调“在计算机上实现协议应该开…

28335接两个spi设备_IIC和SPI如此流行,谁才是嵌入式工程师的必备工具?

IICvs SPI现今&#xff0c;在低端数字通信应用领域&#xff0c;我们随处可见 IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种通信协议非常适合近距离低速芯片间通信。Philips(for IIC)和 Motorola(for SPI) 出于不同背景和市场需求…

线性表15|魔术师发牌问题和拉丁方阵 - 数据结构和算法20

线性表15 : 魔术师发牌问题和拉丁方阵 让编程改变世界 Change the world by program 题外话 今天小甲鱼看到到微博有朋友在问&#xff0c;这个《数据结构和算法》系列课程有木有JAVA版本的&#xff1f; 因为这个问题之前也有一些朋友问过&#xff0c;所以咱在这里统一说下哈…

[ZT]Three ways to tell if a .NET Assembly is Strongly Named (or has Strong Name)

Here are several convenient ways to tell whether a .NET assembly is strongly named. (English language note: I assume the form “strongly named” is preferred over “strong named” since that’s the form used in the output of the sn.exe tool shown immediat…

rstudio 修改代码间距_第一章 R和RStudio

R与RStudioR是一种统计学编程语言&#xff0c;在科学计算领域非常流行。它是由Ross Ihaka和Robert Gentleman开发的&#xff0c;是 "S "编程语言的开源实现。R也是使用这种语言进行统计计算的软件的名字。它有一个庞大的在线支持社区和专门的软件包&#xff0c;可以为…