单继承--多态性 多继承--二义性 ambiguous
一.单继承 –多态性
二.多继承- 二义性ambiguous
- 多个直接父类中 出现同名成员时产生的二义性
- 同一个父类 通过不同继承路径产生的二义性
例8-6 A1父类中的f1(),还是A2父类中的f1()
#include <iostream>
using namespace std;
class A1
{ public:
void f1()
{ cout<<"A1类中的函数f1()"<<endl; }
};
class A2
{ public:
void f1()
{ cout<<"A2类中的函数f1()"<<endl; } // 该成员与A1中的重名
};
class B:public A1,public A2
{
};
int main()
{
B b;
b.f1(); // 该句出错
}
#include <iostream>
using namespace std;
class A1
{ public:
void f1()
{ cout<<"A1类中的函数f1()"<<endl; }
};
class A2
{ public:
void f1()
{ cout<<"A2类中的函数f1()"<<endl; } // 该成员与A1中的重名
};
class B:public A1,public A2
{
};
int main()
{
B b;
b.A1::f1(); // 作用域运算符
b.A2::f1();
}
#include <iostream>
using namespace std;
class A1
{ public:
void f1()
{ cout<<"A1类中的函数f1()"<<endl; }
};
class A2
{ public:
void f1()
{ cout<<“A2类中的函数f1()”<<endl; // 该成员与A1中的重名 }
void f2()
{ cout<<"A2类中的函数f2()"<<endl; }
};
class B:public A1,public A2
{ public:
void f2()
{ cout<<"派生类B中的函数f2()"<<endl; } // 与基类A2中的成员同名
void f3()
{ cout<<"派生类B中的函数f3()"<<endl; }
};
void main()
{ B b;
b.f1(); // 该句出错
b.f2();
b.f3();
}
程序在编译时会出错,错误信息如下:
error C2385: 'B::f1' is ambiguous
warning C4385: could be the 'f1' in base 'A1' of class 'B'
warning C4385: or the 'f1' in base 'A2' of class 'B'
A1类中有一个函数成员f1(),A2类中也有一个同名的函数成员f1(),
派生类B中继承了这两个同名的成员,
类B的对象b对f1()的访问b.f1()出现了二义性,无法确定访问A1类中的f1(),还是A2类中的f1()?
解决方法:
使用作用域运算符“::”明确指出访问的是从哪个类中继承的成员。
例如:将b.f1()写成b.A1::f1();或b.A2::f1();
程序中,A2类和B类中还有一个同名的函数成员f2(),但b对f2的访问b.f2();在编译时并没有出错。
在类的继承层次结构中,基类和派生类具有包含关系,派生类在内层,基类在外层。
同名覆盖
具有包含关系的两个或多个作用域,如果在外层中声明的标识符在内层中没有同名标识符,则它在内层可见,如果内层中声明了同名标识符,则外层标识符在内层不可见,也就是内层标识符覆盖了外层的同名标识符
B类和A1类、B类和A2类都具有包含关系,对于B类和A2类,A2类在外层,B类在内层,这样,根据可见性原则,可知b.f2()访问的是B类的f2()。
void main()
{ B b;
b.A1::f1();
b.A2::f1();
b.f2();
b.f3();
}
这时,没有出现二义性
多层继承中 使用作用域运算符==延伸例8-7
#include <iostream>
using namespace std;
class A
{ public:
void fun()
{ cout<<"A类的函数fun()"<<endl; }
};
class B:public A
{ public:
void fun() { cout<<"B类的函数fun()"<<endl;}
};
class C:public B
{ public:
void fun() { cout<<"C类的函数fun()"<<endl; }
};
class D:public C
{ public:
void f() { C::fun(); B::fun(); A::fun(); }
};
void main()
{ D d;
d.f();
}
例8-8如果一个派生类C 从多个基类B1 B2派生,而这些基类又有一个共同的老基类A,当对该老基类A中说明的成员进行访问时,也可能出现的二义性
#include <iostream>
using namespace std;
class A
{ public:
void fun()
{ cout<<"A类的函数fun()"<<endl; }
};
class B1:public A
{ };
class B2:public A
{ };
class C:public B1,public B2
{ };
void main()
{ C c;
c.fun();
}
程序在编译时出错,错误信息如下:
error C2385: 'C::fun' is ambiguous
warning C4385: could be the 'fun' in base 'A' of base 'B1' of class 'C'
warning C4385: or the 'fun' in base 'A' of base 'B2' of class 'C'
图(b)中,类C继承两个基类B1和B2,而B1和B2又有一个共同的基类A,这样,类A是派生类C在两条继承路径上的公共基类,这个公共基类在派生类C的对象中将包含两个基类A的子对象,从而导致对基类成员访问时的不唯一性,
将基类A定义为虚基类,能够使得公共基类A在派生类中只产生一个子对象,就可避免二义性问题
法(一)作用域运算符
#include <iostream>
using namespace std;
class A
{ public:
void fun() { cout<<"A类的函数fun()"<<endl; }
};
class B1:public A { };
class B2:public A { };
class C:public B1,public B2 { };
main()
{ C c;
c.B1::fun();
c.B2::fun();
}
法(二)虚基类
#include <iostream>
using namespace std;
class A
{ public:
void fun() { cout<<"A类的函数fun()"<<endl; }
};
class B1:virtual public A { };
class B2:public virtual A { };
class C:public B1,public B2 { };
void main()
{ C c;
c.fun();
}
单继承--多态性 多继承--二义性 ambiguous相关推荐
- Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)
Python 在子类中调用父类方法详解(单继承.多层继承.多重继承) by:授客 QQ:1033553122 测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...
- python中的单继承,多继承和mro顺序
python作为一门动态语言,是和c++一样支持面向对象编程的.相对对象编程有三大特性,分别是继承,封装和多态.今天我们重点讲解的是,python语言中的单继承和多继承. 继承概念: 如果一个类继承了 ...
- Python OOP:继承、单继承、多继承、__mro__、子类重写父类同名属性和方法、子类调用父类同名属性和方法、多层继承、super()、私有(实例)属性和方法、获取修改私有属性值、私有类属性
一.继承 Python⾯向对象的继承指的是多个类之间的所属关系,即⼦类默认继承⽗类的所有属性和⽅法. 继承作用:继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展. 在P ...
- C++对象模型:单继承,多继承,虚继承
什么是对象模型 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各种支持的底层实现机制. 类中成员分类 数据成员分为静态和非静态,成员函数有静态非静态以及虚函数 cla ...
- Java_单继承和多继承
1 /* 2 继承: 3 好处:提高了代码的复用性,让类与类之间产生了关系. 4 将对象中的共性内容不断的向上抽取,就形成了关系,就有了继承,有了子父类, 5 提高了代码的复用 6 7 继承特点: 8 ...
- java单继承和多继承
java单继承和多继承 单线程:一个子类只能继承自一个父类 多线程:一个子类可以继承自多个父类 java继承关键字extend和implement,Java所有子类都继承自 java.lang.Obj ...
- C++ - 多态(2) | 虚表的打印、单继承与多继承的虚表
之前的文章中我们介绍了多态的原理以及虚表的知识,本文中我们将继续对多态进行更加深入的学习. 单继承中的虚函数表 虚函数表(虚表)的本质是一个函数指针数组,虚函数的地址会进入虚表.首先我们来看一下这样的 ...
- 简明阐述Java到底是单继承还是多继承?
一.先上结论: 这个问题要分为类和接口两种情况来谈. 即Java中支持的是类的单继承以及接口的多继承(不过其实我们通常对于接口会说实现,而不是继承).所以也会有'Java中支持的是类的单继承以及接口的 ...
- iOS严谨单例写法/可继承单例
单例模式在iOS开发中可能算是最常用的模式之一了,但是由于OC本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦. 今天就来说一说, 单例创建的方式和严谨的单例写法及可继承单例编写. 基本单例的 ...
最新文章
- 德国版“非升即走”引发学界震荡!“临时工”干12年也难获教职,网友:全世界都在卷...
- 快速搭建一个网关服务,动态路由、鉴权看完就会(含流程图)
- 第十六届全国大学生智能车竞赛全部比赛胜利结束了
- 路由器启动后如何定位IOS?
- logisim无法打开解决办法
- 带你自学Python系列(十三):Python函数的用法(三)
- 通过jquer连接数据库里面的数据、LINQ简介
- 为什么阿里巴巴的市值比京东高,世界500排名比京东靠后?
- PCA算法的原理C++ Eigen库实现(附源码下载)
- VRTK HTC手柄发出射线,瞬移,选择物体 VRTK和steamVR对应版本
- dos批处理文件中使用vbs
- 三菱PLC传送类指令应用
- 联通的G网和C网分别是什么意思?
- dubbo之@Adaptive注解分析
- Android 内部存储和外部存储
- 一个dht网络的“磁力链接”搜索python代码
- PLSQL执行SQL脚本文件「适用批量」- 工具使用篇
- 硬件开发者之路之运放共模电压的解释
- day 63 Django基础九之中间件
- linux录屏和截图软件
热门文章
- Deep Learning for 3D Point Clouds: A Survey 论文阅读
- RGB图像重建非刚性物体三维形状(CVPR)
- 时空穿越!谷歌利用众包老照片还原儿时3D街景,浏览器即可体验
- 吊打一切的YOLOv4的tricks汇总!附参考论文下载
- React + Threejs + Swiper 实现全景图效果
- iclr 2020 | Geom-GCN:几何图神经网络
- LaTeX 中表格的用法总结(四)——三线表和复杂的表格
- 遗传:细菌、真菌和动植物的泛基因组研究进展
- 134人!国家重点研发计划“生物大分子与微生物组”重点专项会评专家名单
- 易生信高级转录组分析和数据可视化-最后一天报名