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,一经查实,立即删除!

相关文章

Javascript的IE和Firefox兼容性汇编

window.event现有问题&#xff1a;使用 window.event 无法在 FF 上运行解决方法&#xff1a;FF 的 event 只能在事件发生的现场使用&#xff0c;此问题暂无法解决。可以这样变通&#xff1a;原代码(可在IE中运行)&#xff1a;<input type"button" name"someB…

Java Double类compareTo()方法与示例

双类compareTo()方法 (Double class compareTo() method) compareTo() method is available in java.lang package. compareTo()方法在java.lang包中可用。 compareTo() method is used to check equality or inequality for this Double-object against the given Double-obje…

平院实训门禁系统导入

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

ffmpeg 解码音频(aac、mp3)输出pcm文件

ffmpeg 解码音频&#xff08;aac、mp3&#xff09;输出pcm文件 播放pcm可以参考&#xff1a; ffplay -ar 48000 -ac 2 -f f32le out.pcm main.c #include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavutil/frame.h> #include …

Jquery getJSON()

getJSON与aspx 准备工作 Customer类 public class Customer{public int Unid { get; set; }public string CustomerName { get; set; }public string Memo { get; set; }public string Other { get; set; }}&#xff08;一&#xff09;ashx Customer customer new Customer { …

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

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

Java ClassLoader getPackage()方法与示例

ClassLoader类的getPackage()方法 (ClassLoader Class getPackage() method) getPackage() method is available in java.lang package. getPackage()方法在java.lang包中可用。 getPackage() method is used to return the package that has been defined in ClassLoader or t…

C---编写程序:求出1~1000之间能被7或12整除,但不能同时被二者整除的所有整数,将结果保存在数组中,要求程序数据的输入、计算和输出均使用函数实现。

编写程序&#xff1a;求出1~1000之间能被7或12整除&#xff0c;但不能同时被二者整除的所有整数&#xff0c;将结果保存在数组中&#xff0c;要求程序数据的输入、计算和输出均使用函数实现。 编程思路&#xff1a;分别编写函数input()、cal()、output()实现数据的输入、计算和…

报告称我国成最大移民输出国 将形成投资产业链(关注)

时代特有的现象&#xff0c;我们应该予以关注 “现在国内房价这么高&#xff0c;政策也看不清&#xff0c;还不如逢高卖掉之前买的几套房子&#xff0c;一两套房子的钱办个投资移民&#xff0c;趁还年轻&#xff0c;拿到绿卡后享受一下美国本国待遇的高等教育了。”广州&#x…

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

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

ffmpeg 解码视频(h264、mpeg2)输出yuv420p文件

ffmpeg 解码视频&#xff08;h264、mpeg2&#xff09;输出yuv420p文件 播放yuv可以参考&#xff1a;ffplay -pixel_format yuv420p -video_size 768x320 -framerate 25 out.yuv main.c #include <stdio.h> #include <stdlib.h> #include <string.h>#includ…

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

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

C---编写程序:实现一个随堂测试,能进行加减乘除运算。要求如下:(1)随机产生两个1~10的正整数,在屏幕上输出题目,如:5+3=?(2)学生输入答案,程序检查学生输入答案是否正确,若正确,

编写程序&#xff1a;实现一个随堂测试&#xff0c;能进行加减乘除运算。要求如下&#xff1a; 1&#xff09;随机产生两个1~10的正整数&#xff0c;在屏幕上输出题目&#xff0c;如&#xff1a;53&#xff1f; 2&#xff09;学生输入答案&#xff0c;程序检查学生输入答案是…

分析一下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…

利用SQL注入2分钟入侵网站

说起流光、溯雪、乱刀&#xff0c;可以说是大名鼎鼎无人不知无人不晓&#xff0c;这些都是小榕哥的作品。每次一提起小榕哥来&#xff0c;我的崇拜景仰就如滔滔江水&#xff0c;连绵不绝~~~~&#xff08;又来了&#xff01;&#xff09; 让我们崇拜的小榕哥最新又发布了SQL注入…

pip安装deb_技术|如何在 Ubuntu 上安装 pip

pip 是一个命令行工具&#xff0c;允许你安装 Python 编写的软件包。 学习如何在 Ubuntu 上安装 pip 以及如何使用它来安装 Python 应用程序。有许多方法可以在 Ubuntu 上安装软件。 你可以从软件中心安装应用程序&#xff0c;也可以从下载的 DEB 文件、PPA(LCTT 译注&#xff…

assubclass_Java类class asSubclass()方法及示例

assubclass类类asSubclass()方法 (Class class asSubclass() method) asSubclass() method is available in java.lang package. asSubclass()方法在java.lang包中可用。 asSubclass() method casts this Class object to denote a subclass of the class denoted by the given…

VB6.0 怎样启用控件comdlg32.ocx

VB6.0 怎样启用控件comdlg32.ocx 怎样启用控件comdlg32.ocx 2008-10-08 09:32 提问者&#xff1a; nefu_20061617 |浏览次数&#xff1a;1502次vbs文件中有代码Set ComDlg CreateObject("MSComdlg.CommonDialog")运行时发生错误ActiveX 部件不能创建对象: MSComdlg.…

Python---爬虫案例

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

WinCE驱动开发问题精华集锦(二)

转自&#xff1a;http://hgh123.blog.163.com/blog/static/5980422120086183115543/ 感谢 我怎么能在PB左边的定制平台加进我的驱动呢&#xff1f; 两种办法&#xff1a; 1、在platform.bib或者project.bib的MODULES部分添加一条语句&#xff0c;例如&#xff1a; MyDriver.dll…