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 1
i am B1,my num is 2
i am B2,my num is 3
i am D,my num is 4
Member of Bo

C++多重继承二义性解决的更多相关文章

  1. C++学习之路—继承与派生(三):多重继承与虚基类

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...

  2. C++学习之虚继承

    http://blog.csdn.net/wangxingbao4227/article/details/6772579 C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同 ...

  3. 虚拟继承C++

    C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类.这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数 ...

  4. C++虚继承的概念[转]

    C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类.这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数 ...

  5. C/C++面试题总结(1)

    首先说一下,这些东西,有的是必须掌握的,有的是面试时你讲出来就是闪光点.自己把握.把握不好的都搞懂.实在不行背下来. 由于时间关系,总结的比较随意,有的就直接贴链接了,希望理解一下. 第一篇:基础(必 ...

  6. C++虚继承的概念(转)

    http://blog.csdn.net/wangxingbao4227/article/details/6772579 C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同 ...

  7. C++虚继承作用

    C++虚继承可以防止多重继承产生的二义性问题. 虚继承,就是在被继承的类前面加上virtual关键字,这时被继承的类称为虚基类,如下面代码中的base类.虚继承在多重继承的时可以防止二义性. clas ...

  8. C++笔记(仅C++特性,需C语言基础)

    C++复习笔记一(类的声明定义应用与构造函数析构函数部分)const在C语言中是"不能被改变值的变量",而在C++种子则是"一种有类型描述的常量",常量必须初始 ...

  9. c/c++: c++继承 内存分布 虚表 虚指针 (转)

    http://www.cnblogs.com/DylanWind/archive/2009/01/12/1373919.html 前部分原创,转载请注明出处,谢谢! class Base  {  pu ...

随机推荐

  1. 剑指offer中数据结构与算法部分学习

    2.3.4 树 遍历:前中后序,宽度优先. 二叉树的特例:二叉搜索树.堆(最大堆和最小堆,用于找最值).红黑树(c++ STL中的很多数据结果就是基于这实现的): 题7-重建二叉树:递归,设置四个位点 ...

  2. Python的数值和字符串

    Python数据类型 1.数值 --类型:  1/整型 2/长整型   3/浮点型 -- 0.0, 12.0, -18.8, 3e+7等 4/复数型 -- complex  In []: 0x34al ...

  3. 【Android开发日记】之基础篇(二)——Android的动画效果

          什么是动画,动画的本质是通过连续不断地显示若干图像来产生“动”起来的效果.比如说一个移动的动画,就是在一定的时间段内,以恰当的速率(起码要12帧/秒以上,才会让人产生动起来的错觉)每隔若干 ...

  4. SPOJ 375

    默默一看提交时间 -- 这是我以前的代码风格-- #include <cstdio> #include <cstring> #include <vector> #i ...

  5. 【python】发送邮件

    从网上找了一些用python发邮件的教程,学习一下: 1.发送普通的文本邮件 http://www.cnblogs.com/xiaowuyi/archive/2012/03/17/2404015.ht ...

  6. POJ-3268

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13738   Accepted: 6195 ...

  7. mysql中json数据的拼接方式

    SELECT CONCAT('[', GROUP_CONCAT( CONCAT('{"id":"',STRUCTURE_ID,'"'),',', CONCAT( ...

  8. win 10 用户上传头像保存的文件夹路径

    win 10 用户上传头像保存的文件夹路径 C:\Users\Administrator(用户名)\AppData\Roaming\Microsoft\Windows\AccountPictures

  9. [putty] ubuntu 通过配置文件设置字体

    创建了一个session之后,就能在 ~/.putty/sessions/ 文件夹下看到session的配置文件了 $ vim ~/.putty/sessions/session-name 搜索Fon ...

  10. sublime插件总汇

    本人用过多个编辑器(非IDE),发现sublime的样式非常帮,现在做个插件总汇 ChineseLocalzations      中文插件 Emmet                         ...