C++多重继承二义性解决
1. 什么是多重继承的二义性
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class A{public: void f();}class B{public: void f(); void g();}class C:public A,public B{public: void g(); void h();}; |
如果声明:C c1,则c1.f();具有二义性,而c1.g();无二义性(同名覆盖)。
2. 解决办法一 -- 类名限定
调用时指名调用的是哪个类的函数,如
|
1
2
|
c1.A::f();c1.B::f(); |
3. 解决办法二 -- 同名覆盖
在C中声明一个同名函数,该函数根据需要内部调用A的f或者是B的f。如
|
1
2
3
4
5
6
7
8
|
class C:public A,public B{public: void g(); void h(); void f(){ A::f(); }}; |
4. 解决办法三 -- 虚基类(用于有共同基类的场合)
virtual 修饰说明基类,如:
|
1
|
class B1:virtual public B |
虚基类主要用来解决多继承时,可能对同一基类继承继承多次从而产生的二义性。为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝。注意:需要在第一次继承时就要将共同的基类设计为虚基类。虚基类及其派生类构造函数建立对象时所指定的类称为最(远)派生类。
- 虚基类的成员是由派生类的构造函数通过调用虚基类的构造函数进行初始化的。
- 在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的缺省构造函数。
- 在建立对象时,只有最派生类的构造函数调用虚基类的构造函数,该派生类的其他基类对虚基类的构造函数的调用被忽略。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class B{ public: int b;}class B1:virtual public B{ priavte: int b1;}class B2:virutual public B{ private: int b2;}class C:public B1,public B1{ private: float d;}C obj;obj.b;//正确的 |
如果B1和B2不采用虚继续,则编译出错,提示“request for member 'b' is ambiguous”。这是因为,不指名virtual的继承,子类将父类的成员都复制到自己的空间中,所以,C中会有两个b。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
#include<iostream>using namespace std;class B0{public: B0(int n) { nv=n; cout<<"i am B0,my num is"<<nv<<endl; } void fun() { cout<<"Member of Bo"<<endl; }private: int nv;};class B1:virtual public B0{public: B1(int x,int y):B0(y){ nv1=x; cout<<"i am B1,my num is "<<nv1<<endl; }private: int nv1;};class B2:virtual public B0{public: B2(int x,int y):B0(y){ nv2=x; cout<<"i am B2,my num is "<<nv2<<endl; }private: int nv2;};class D:public B1,public B2{public: D(int x,int y,int z,int k):B0(x),B1(y,y),B2(z,y){ nvd=k; cout<<"i am D,my num is "<<nvd<<endl; }private: int nvd;};int main(){ D d(1,2,3,4); d.fun(); return 0;} |
d.fun()的结果是:
|
1
2
3
4
5
|
i am B0,my num is 1i am B1,my num is 2i am B2,my num is 3i am D,my num is 4Member of Bo |
C++多重继承二义性解决的更多相关文章
- C++学习之路—继承与派生(三):多重继承与虚基类
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...
- C++学习之虚继承
http://blog.csdn.net/wangxingbao4227/article/details/6772579 C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同 ...
- 虚拟继承C++
C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类.这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数 ...
- C++虚继承的概念[转]
C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类.这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数 ...
- C/C++面试题总结(1)
首先说一下,这些东西,有的是必须掌握的,有的是面试时你讲出来就是闪光点.自己把握.把握不好的都搞懂.实在不行背下来. 由于时间关系,总结的比较随意,有的就直接贴链接了,希望理解一下. 第一篇:基础(必 ...
- C++虚继承的概念(转)
http://blog.csdn.net/wangxingbao4227/article/details/6772579 C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同 ...
- C++虚继承作用
C++虚继承可以防止多重继承产生的二义性问题. 虚继承,就是在被继承的类前面加上virtual关键字,这时被继承的类称为虚基类,如下面代码中的base类.虚继承在多重继承的时可以防止二义性. clas ...
- C++笔记(仅C++特性,需C语言基础)
C++复习笔记一(类的声明定义应用与构造函数析构函数部分)const在C语言中是"不能被改变值的变量",而在C++种子则是"一种有类型描述的常量",常量必须初始 ...
- c/c++: c++继承 内存分布 虚表 虚指针 (转)
http://www.cnblogs.com/DylanWind/archive/2009/01/12/1373919.html 前部分原创,转载请注明出处,谢谢! class Base { pu ...
随机推荐
- 【UOJ#164】清华集训2015V
QwQzcysky真是菜死了,这是我刚上高一的时候坤爷在夏令营讲的,可是今天才切掉…… 想想也神奇,一个2016.11才学会线段树的菜鸡,夏令营的时候居然听过Segment-Tree-Beats? 所 ...
- popup menu案例,无说明只代码
效果图: 布局文件, 展示列表的容器 <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...
- Spring,tk-mapper源码阅读
Mybatis的源码学习(一): 前言: 结合spring本次学习会先从spring-mybatis开始分析 在学习mybatis之前,应该要对spring的bean有所了解,本文略过 先贴一下myb ...
- [linux]通过ssh远程设定各服务器时间,从而实现集群时间同步
#!/usr/bin/env bash #all hosts should to sync time, all hosts should no password login echo other sy ...
- 安装lszrz,用于上传文件
wget http://down1.chinaunix.net/distfiles/lrzsz-0.12.20.tar.gztar zxvf lrzsz-0.12.20.tar.gzcd lrzsz- ...
- Name Disambiguation in AMiner-Clustering, Maintenance, and Human in the Loop
Name Disambiguation in AMiner: Clustering, Maintenance, and Human in the Loop paper:http://keg.cs.ts ...
- 同步方法-java
除了同步代码块能实现同步执行外,同步方法也可以. 先看下同步代码块实现同步执行: public class Demo4 { public static void main(String[] args) ...
- django “如何”系列8:如何为模型提供初始化数据
当你第一次配置一个app的时候,有时候使用硬编码的数据去预填充你的数据库是非常有用的.这里有几个你可以让django自动创建这些数据的方法:你可以提供固定格式的初始化数据或者提供通过SQL初始化数据. ...
- SecureCrt的操持连接办法
保持连接: options -> global options -> General -> Default Session,点击Edit default settings按钮,在Te ...
- LocalStorage、SessionStorage使用详解
https://blog.csdn.net/zhongzh86/article/details/55504381