网站建设2018,域名网安备案,南阳做网站公司电话,阿里+wordpress多重继承前面我们介绍的派生类只有一个基类#xff0c;称为单基派生或单一继承。在实际运用中#xff0c;我们经常需要派生类同时具有多个基类#xff0c;这种方法称为多基派生或多重继承。2.1 多重继承的声明#xff1a;在 C 中#xff0c;声明具有两个以上基类的派生类与…多重继承前面我们介绍的派生类只有一个基类称为单基派生或单一继承。在实际运用中我们经常需要派生类同时具有多个基类这种方法称为多基派生或多重继承。2.1 多重继承的声明在 C 中声明具有两个以上基类的派生类与声明单基派生类的形式类似只需将要继承的多个基类用逗号分开即可。在多重继承中公有派生和私有派生对于基类成员在派生类的可访问性与单继承的规则相同。另外对基类成员的访问必须是无二义的若两个基类中具有同名的数据成员或成员函数使用成员名限定来消除二义性若派生类中新增成员或成员函数与基类成员或成员函数同名则派生类会覆盖外层同名成员也须使用作用域分辨符。2.2 多重继承的构造函数和析构函数多重继承的构造函数的定义形式与单继承构造函数的定义形式类似只有 n 个基类的构造函数之间用“”分隔。多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同也是遵循先执行基类的构造函数再执行对象成员的构造函数最后执行派生类构造函数的原则。在多个基类之间则严格按照派生类声明是从左到右的顺序来排列先后。而析构函数的执行顺序与构造函数的执行顺序相反。2.3 虚基类 :如果某个派生类的部分或全部直接基类是从另一个共同的基类派生而来在这些基类中从上一级基类继承来的成员就有相同的名称则在这个派生类中访问这个共同的基类中的成员时可能会产生二义性此时可定义虚基类。这就要求在其直接基类的定义中使用关键字 virtual 将那个共同的基类定义为虚基类其语法形式如下class 派生类名 virtual 派生方式 基类虚基类的初始化与一般的多重继承的初始化在语法上是一样的 但构造函数的调用顺序不同虚基类构造函数的调用顺序是这样规定的1) 在同一层次中先调用虚基类的构造函数接下来依次是非虚基类的构造函数对象成员的构造函数派生类的构造函数。2) 若同一层次中包含多个虚基类这些虚基类的构造函数按对他们说明的先后次序调用3) 若虚基类由非虚基类派生而来则仍然先调用基类构造函数再调用派生类构造函数。 上面是理论有点儿晦涩下面举一个例子.以下图为例 接口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中的方法即可。CAIB必须以这个顺序出现 对于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(){coutCB::FuncInBendl;return 2;};/*virtual int FuncInA(){coutCB::FuncInA Call CA::FuncInA() CA::FuncInA()endl;return 3;};*/}; 上面的代码编译可以通过且结果如期望。如果去掉virtual继承修饰符就会报错。转载于:https://www.cnblogs.com/sgsoft/archive/2010/07/20/1781724.html